Source Code Cross Referenced for ModuleListParser.java in  » IDE-Netbeans » nbbuild » org » netbeans » nbbuild » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE Netbeans » nbbuild » org.netbeans.nbbuild 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003:         *
0004:         * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
0005:         *
0006:         * The contents of this file are subject to the terms of either the GNU
0007:         * General Public License Version 2 only ("GPL") or the Common
0008:         * Development and Distribution License("CDDL") (collectively, the
0009:         * "License"). You may not use this file except in compliance with the
0010:         * License. You can obtain a copy of the License at
0011:         * http://www.netbeans.org/cddl-gplv2.html
0012:         * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
0013:         * specific language governing permissions and limitations under the
0014:         * License.  When distributing the software, include this License Header
0015:         * Notice in each file and include the License file at
0016:         * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
0017:         * particular file as subject to the "Classpath" exception as provided
0018:         * by Sun in the GPL Version 2 section of the License file that
0019:         * accompanied this code. If applicable, add the following below the
0020:         * License Header, with the fields enclosed by brackets [] replaced by
0021:         * your own identifying information:
0022:         * "Portions Copyrighted [year] [name of copyright owner]"
0023:         *
0024:         * Contributor(s):
0025:         *
0026:         * The Original Software is NetBeans. The Initial Developer of the Original
0027:         * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
0028:         * Microsystems, Inc. All Rights Reserved.
0029:         *
0030:         * If you wish your version of this file to be governed by only the CDDL
0031:         * or only the GPL Version 2, indicate your decision by adding
0032:         * "[Contributor] elects to include this software in this distribution
0033:         * under the [CDDL or GPL Version 2] license." If you do not indicate a
0034:         * single choice of license, a recipient has the option to distribute
0035:         * your version of this file under either the CDDL, the GPL Version 2 or
0036:         * to extend the choice of license to its licensees as provided above.
0037:         * However, if you add GPL Version 2 code and therefore, elected the GPL
0038:         * Version 2 license, then the option applies only if the new code is
0039:         * made subject to such option by the copyright holder.
0040:         */
0041:
0042:        package org.netbeans.nbbuild;
0043:
0044:        import java.io.BufferedInputStream;
0045:        import java.io.File;
0046:        import java.io.FileInputStream;
0047:        import java.io.FileOutputStream;
0048:        import java.io.IOException;
0049:        import java.io.InputStream;
0050:        import java.io.ObjectInput;
0051:        import java.io.ObjectInputStream;
0052:        import java.io.ObjectOutput;
0053:        import java.io.ObjectOutputStream;
0054:        import java.io.OutputStream;
0055:        import java.io.Serializable;
0056:        import java.util.ArrayList;
0057:        import java.util.Arrays;
0058:        import java.util.HashMap;
0059:        import java.util.HashSet;
0060:        import java.util.Hashtable;
0061:        import java.util.Iterator;
0062:        import java.util.List;
0063:        import java.util.Map;
0064:        import java.util.Set;
0065:        import java.util.StringTokenizer;
0066:        import java.util.TreeSet;
0067:        import java.util.jar.Attributes;
0068:        import java.util.jar.JarFile;
0069:        import org.apache.tools.ant.BuildListener;
0070:        import org.apache.tools.ant.Project;
0071:        import org.apache.tools.ant.taskdefs.Property;
0072:        import org.apache.tools.ant.types.Path;
0073:        import org.apache.tools.ant.util.FileUtils;
0074:        import org.w3c.dom.Document;
0075:        import org.w3c.dom.Element;
0076:        import org.xml.sax.InputSource;
0077:
0078:        /**
0079:         * Scans for known modules.
0080:         * Precise algorithm summarized in issue #42681 and issue #58966.
0081:         * @author Jesse Glick
0082:         */
0083:        final class ModuleListParser {
0084:
0085:            private static Map<File, Map<String, Entry>> SOURCE_SCAN_CACHE = new HashMap<File, Map<String, Entry>>();
0086:            private static Map<File, Map<String, Entry>> SUITE_SCAN_CACHE = new HashMap<File, Map<String, Entry>>();
0087:            private static Map<File, Entry> STANDALONE_SCAN_CACHE = new HashMap<File, Entry>();
0088:            private static Map<File, Map<String, Entry>> BINARY_SCAN_CACHE = new HashMap<File, Map<String, Entry>>();
0089:
0090:            /** Clear caches. Cf. #71130. */
0091:            public static void resetCaches() {
0092:                SOURCE_SCAN_CACHE.clear();
0093:                SUITE_SCAN_CACHE.clear();
0094:                STANDALONE_SCAN_CACHE.clear();
0095:                BINARY_SCAN_CACHE.clear();
0096:            }
0097:
0098:            /** Synch with org.netbeans.modules.apisupport.project.universe.ModuleList.FOREST: */
0099:            private static final String[] FOREST = {
0100:            /*root*/null, "contrib",
0101:            // do not scan in misc; any real modules would have been put in contrib
0102:            // Will there be other subtrees in the future (not using suites)?
0103:            };
0104:
0105:            /**
0106:             * Find all NBM projects in a root, possibly from cache.
0107:             */
0108:            private static Map<String, Entry> scanNetBeansOrgSources(File root,
0109:                    Hashtable<String, String> properties, Project project)
0110:                    throws IOException {
0111:                Map<String, Entry> entries = SOURCE_SCAN_CACHE.get(root);
0112:                if (entries == null) {
0113:                    // Similar to #62221: if just invoked from a module in standard clusters, only scan those clusters (faster):
0114:                    Set<String> standardModules = new HashSet<String>();
0115:                    boolean doFastScan = false;
0116:                    String basedir = properties.get("basedir");
0117:                    if (basedir != null) {
0118:                        File basedirF = new File(basedir);
0119:                        String clusterList = properties.get("nb.clusters.list");
0120:                        if (clusterList == null) {
0121:                            String config = properties.get("cluster.config");
0122:                            if (config != null) {
0123:                                clusterList = properties.get("clusters.config."
0124:                                        + config + ".list");
0125:                            }
0126:                        }
0127:                        if (clusterList != null) {
0128:                            StringTokenizer tok = new StringTokenizer(
0129:                                    clusterList, ", ");
0130:                            while (tok.hasMoreTokens()) {
0131:                                String clusterName = tok.nextToken();
0132:                                String moduleList = properties.get(clusterName);
0133:                                if (moduleList != null) {
0134:                                    StringTokenizer tok2 = new StringTokenizer(
0135:                                            moduleList, ", ");
0136:                                    while (tok2.hasMoreTokens()) {
0137:                                        String module = tok2.nextToken();
0138:                                        standardModules.add(module);
0139:                                        doFastScan |= new File(root, module
0140:                                                .replace('/',
0141:                                                        File.separatorChar))
0142:                                                .equals(basedirF);
0143:                                    }
0144:                                }
0145:                            }
0146:                        }
0147:                    }
0148:                    File scanCache = new File(root, "nbbuild"
0149:                            + File.separatorChar + "nbproject"
0150:                            + File.separatorChar + "private"
0151:                            + File.separatorChar + "scan-cache-"
0152:                            + (doFastScan ? "standard" : "full") + ".ser");
0153:                    if (scanCache.isFile()) {
0154:                        if (project != null) {
0155:                            project
0156:                                    .log("Loading module list from "
0157:                                            + scanCache);
0158:                        }
0159:                        try {
0160:                            InputStream is = new FileInputStream(scanCache);
0161:                            try {
0162:                                ObjectInput oi = new ObjectInputStream(
0163:                                        new BufferedInputStream(is));
0164:                                @SuppressWarnings("unchecked")
0165:                                Map<File, Long[]> timestampsAndSizes = (Map) oi
0166:                                        .readObject();
0167:                                boolean matches = true;
0168:                                for (Map.Entry<File, Long[]> entry : timestampsAndSizes
0169:                                        .entrySet()) {
0170:                                    File f = entry.getKey();
0171:                                    if (f.lastModified() != entry.getValue()[0]
0172:                                            || f.length() != entry.getValue()[1]) {
0173:                                        if (project != null) {
0174:                                            project
0175:                                                    .log("Cache ignored due to modifications in "
0176:                                                            + f);
0177:                                        }
0178:                                        matches = false;
0179:                                        break;
0180:                                    }
0181:                                }
0182:                                if (doFastScan) {
0183:                                    @SuppressWarnings("unchecked")
0184:                                    Set<String> storedStandardModules = (Set) oi
0185:                                            .readObject();
0186:                                    if (!standardModules
0187:                                            .equals(storedStandardModules)) {
0188:                                        Set<String> added = new TreeSet<String>(
0189:                                                standardModules);
0190:                                        added.removeAll(storedStandardModules);
0191:                                        Set<String> removed = new TreeSet<String>(
0192:                                                storedStandardModules);
0193:                                        removed.removeAll(standardModules);
0194:                                        project
0195:                                                .log("Cache ignored due to changes in modules among standard clusters: + "
0196:                                                        + added
0197:                                                        + " - "
0198:                                                        + removed);
0199:                                        matches = false;
0200:                                    }
0201:                                }
0202:                                File myProjectXml = project
0203:                                        .resolveFile("nbproject/project.xml");
0204:                                if (myProjectXml.isFile()
0205:                                        && !timestampsAndSizes
0206:                                                .containsKey(myProjectXml)) {
0207:                                    project
0208:                                            .log("Cache ignored since it has no mention of "
0209:                                                    + myProjectXml);
0210:                                    matches = false; // #118098
0211:                                }
0212:                                if (matches) {
0213:                                    @SuppressWarnings("unchecked")
0214:                                    Map<String, Entry> _entries = (Map) oi
0215:                                            .readObject();
0216:                                    entries = _entries;
0217:                                    if (project != null) {
0218:                                        project.log("Loaded modules: "
0219:                                                + entries.keySet(),
0220:                                                Project.MSG_VERBOSE);
0221:                                    }
0222:                                }
0223:                            } finally {
0224:                                is.close();
0225:                            }
0226:                        } catch (Exception x) {
0227:                            if (project != null) {
0228:                                project.log("Error loading " + scanCache + ": "
0229:                                        + x, Project.MSG_WARN);
0230:                            }
0231:                        }
0232:                    }
0233:                    if (entries == null) {
0234:                        entries = new HashMap<String, Entry>();
0235:                        Map<File, Long[]> timestampsAndSizes = new HashMap<File, Long[]>();
0236:                        registerTimestampAndSize(new File(root, "nbbuild"
0237:                                + File.separatorChar + "cluster.properties"),
0238:                                timestampsAndSizes);
0239:                        registerTimestampAndSize(new File(root, "nbbuild"
0240:                                + File.separatorChar + "build.properties"),
0241:                                timestampsAndSizes);
0242:                        registerTimestampAndSize(
0243:                                new File(root, "nbbuild" + File.separatorChar
0244:                                        + "user.build.properties"),
0245:                                timestampsAndSizes);
0246:                        if (doFastScan) {
0247:                            if (project != null) {
0248:                                project.log("Scanning for modules in " + root
0249:                                        + " among standard clusters");
0250:                            }
0251:                            for (String module : standardModules) {
0252:                                scanPossibleProject(new File(root, module
0253:                                        .replace('/', File.separatorChar)),
0254:                                        entries, properties, module,
0255:                                        ParseProjectXml.TYPE_NB_ORG, project,
0256:                                        timestampsAndSizes);
0257:                            }
0258:                        } else {
0259:                            // Might be an extra module (e.g. something in contrib); need to scan everything.
0260:                            if (project != null) {
0261:                                project.log("Scanning for modules in " + root);
0262:                                project.log("Quick scan mode disabled since "
0263:                                        + basedir
0264:                                        + " not among standard modules of "
0265:                                        + root + " which are "
0266:                                        + standardModules, Project.MSG_VERBOSE);
0267:                            }
0268:                            for (String tree : FOREST) {
0269:                                File dir = tree == null ? root : new File(root,
0270:                                        tree);
0271:                                File[] kids = dir.listFiles();
0272:                                if (kids == null) {
0273:                                    continue;
0274:                                }
0275:                                for (File kid : kids) {
0276:                                    if (!kid.isDirectory()) {
0277:                                        continue;
0278:                                    }
0279:                                    String name = kid.getName();
0280:                                    String path = tree == null ? name : tree
0281:                                            + "/" + name;
0282:                                    scanPossibleProject(kid, entries,
0283:                                            properties, path,
0284:                                            ParseProjectXml.TYPE_NB_ORG,
0285:                                            project, timestampsAndSizes);
0286:                                }
0287:
0288:                            }
0289:                        }
0290:                        if (project != null) {
0291:                            project.log("Found modules: " + entries.keySet(),
0292:                                    Project.MSG_VERBOSE);
0293:                            project.log("Cache depends on files: "
0294:                                    + timestampsAndSizes.keySet(),
0295:                                    Project.MSG_DEBUG);
0296:                        }
0297:                        scanCache.getParentFile().mkdirs();
0298:                        OutputStream os = new FileOutputStream(scanCache);
0299:                        try {
0300:                            ObjectOutput oo = new ObjectOutputStream(os);
0301:                            oo.writeObject(timestampsAndSizes);
0302:                            if (doFastScan) {
0303:                                oo.writeObject(standardModules);
0304:                            }
0305:                            oo.writeObject(entries);
0306:                            oo.flush();
0307:                        } finally {
0308:                            os.close();
0309:                        }
0310:                    }
0311:                    SOURCE_SCAN_CACHE.put(root, entries);
0312:                }
0313:                return entries;
0314:            }
0315:
0316:            private static void registerTimestampAndSize(File f,
0317:                    Map<File, Long[]> timestampsAndSizes) {
0318:                if (timestampsAndSizes != null) {
0319:                    timestampsAndSizes.put(f, new Long[] { f.lastModified(),
0320:                            f.length() });
0321:                }
0322:            }
0323:
0324:            /**
0325:             * Check a single dir to see if it is an NBM project, and if so, register it.
0326:             */
0327:            private static boolean scanPossibleProject(File dir,
0328:                    Map<String, Entry> entries,
0329:                    Hashtable<String, String> properties, String path,
0330:                    int moduleType, Project project,
0331:                    Map<File, Long[]> timestampsAndSizes) throws IOException {
0332:                File nbproject = new File(dir, "nbproject");
0333:                File projectxml = new File(nbproject, "project.xml");
0334:                if (!projectxml.isFile()) {
0335:                    return false;
0336:                }
0337:                registerTimestampAndSize(projectxml, timestampsAndSizes);
0338:                Document doc;
0339:                try {
0340:                    doc = XMLUtil.parse(new InputSource(projectxml.toURI()
0341:                            .toString()), false, true, /*XXX*/null, null);
0342:                } catch (Exception e) { // SAXException, IOException (#60295: e.g. encoding problem in XML)
0343:                    // Include \n so that following line can be hyperlinked
0344:                    throw (IOException) new IOException(
0345:                            "Error parsing project file\n" + projectxml + ": "
0346:                                    + e.getMessage()).initCause(e);
0347:                }
0348:                Element typeEl = XMLUtil.findElement(doc.getDocumentElement(),
0349:                        "type", ParseProjectXml.PROJECT_NS);
0350:                if (!XMLUtil.findText(typeEl).equals(
0351:                        "org.netbeans.modules.apisupport.project")) {
0352:                    return false;
0353:                }
0354:                Element configEl = XMLUtil.findElement(
0355:                        doc.getDocumentElement(), "configuration",
0356:                        ParseProjectXml.PROJECT_NS);
0357:                Element dataEl = ParseProjectXml.findNBMElement(configEl,
0358:                        "data");
0359:                if (dataEl == null) {
0360:                    if (project != null) {
0361:                        project
0362:                                .log(
0363:                                        projectxml.toString()
0364:                                                + ": warning: module claims to be a NBM project but is missing <data xmlns=\""
0365:                                                + ParseProjectXml.NBM_NS3
0366:                                                + "\">; maybe an old NB 4.[01] project?",
0367:                                        Project.MSG_WARN);
0368:                    }
0369:                    return false;
0370:                }
0371:                Element cnbEl = ParseProjectXml.findNBMElement(dataEl,
0372:                        "code-name-base");
0373:                String cnb = XMLUtil.findText(cnbEl);
0374:                if (moduleType == ParseProjectXml.TYPE_NB_ORG
0375:                        && project != null) {
0376:                    String expectedDirName = abbreviate(cnb);
0377:                    String actualDirName = dir.getName();
0378:                    if (!actualDirName.equals(expectedDirName)) {
0379:                        throw new IOException(
0380:                                "Expected module to be in dir named "
0381:                                        + expectedDirName
0382:                                        + " but was actually found in dir named "
0383:                                        + actualDirName);
0384:                    }
0385:                }
0386:                // Clumsy but the best way I know of to evaluate properties.
0387:                Project fakeproj = new Project();
0388:                if (project != null) {
0389:                    // Try to debug any problems in the following definitions (cf. #59849).
0390:                    Iterator it = project.getBuildListeners().iterator();
0391:                    while (it.hasNext()) {
0392:                        fakeproj.addBuildListener((BuildListener) it.next());
0393:                    }
0394:                }
0395:                fakeproj.setBaseDir(dir); // in case ${basedir} is used somewhere
0396:                Property faketask = new Property();
0397:                faketask.setProject(fakeproj);
0398:                switch (moduleType) {
0399:                case ParseProjectXml.TYPE_NB_ORG:
0400:                    // do nothing here
0401:                    break;
0402:                case ParseProjectXml.TYPE_SUITE:
0403:                    faketask.setFile(new File(nbproject,
0404:                            "private/suite-private.properties"));
0405:                    faketask.execute();
0406:                    faketask.setFile(new File(nbproject, "suite.properties"));
0407:                    faketask.execute();
0408:                    faketask
0409:                            .setFile(new File(
0410:                                    fakeproj
0411:                                            .replaceProperties("${suite.dir}/nbproject/private/platform-private.properties")));
0412:                    faketask.execute();
0413:                    faketask
0414:                            .setFile(new File(
0415:                                    fakeproj
0416:                                            .replaceProperties("${suite.dir}/nbproject/platform.properties")));
0417:                    faketask.execute();
0418:                    break;
0419:                case ParseProjectXml.TYPE_STANDALONE:
0420:                    faketask.setFile(new File(nbproject,
0421:                            "private/platform-private.properties"));
0422:                    faketask.execute();
0423:                    faketask
0424:                            .setFile(new File(nbproject, "platform.properties"));
0425:                    faketask.execute();
0426:                    break;
0427:                default:
0428:                    assert false : moduleType;
0429:                }
0430:                File privateProperties = new File(nbproject,
0431:                        "private/private.properties".replace('/',
0432:                                File.separatorChar));
0433:                registerTimestampAndSize(privateProperties, timestampsAndSizes);
0434:                faketask.setFile(privateProperties);
0435:                faketask.execute();
0436:                File projectProperties = new File(nbproject,
0437:                        "project.properties");
0438:                registerTimestampAndSize(projectProperties, timestampsAndSizes);
0439:                faketask.setFile(projectProperties);
0440:                faketask.execute();
0441:                faketask.setFile(null);
0442:                faketask.setName("module.jar.dir");
0443:                faketask.setValue("modules");
0444:                faketask.execute();
0445:                assert fakeproj.getProperty("module.jar.dir") != null : fakeproj
0446:                        .getProperties();
0447:                faketask.setName("module.jar.basename");
0448:                faketask.setValue(cnb.replace('.', '-') + ".jar");
0449:                faketask.execute();
0450:                faketask.setName("module.jar");
0451:                faketask
0452:                        .setValue(fakeproj
0453:                                .replaceProperties("${module.jar.dir}/${module.jar.basename}"));
0454:                faketask.execute();
0455:                switch (moduleType) {
0456:                case ParseProjectXml.TYPE_NB_ORG:
0457:                    assert path != null;
0458:                    // Find the associated cluster.
0459:                    for (Map.Entry<String, String> entry : properties
0460:                            .entrySet()) {
0461:                        String val = entry.getValue();
0462:                        String[] modules = val.split(", *");
0463:                        if (Arrays.asList(modules).contains(path)) {
0464:                            String key = entry.getKey();
0465:                            String clusterDir = properties.get(key + ".dir");
0466:                            if (clusterDir != null) {
0467:                                faketask.setName("cluster.dir");
0468:                                faketask.setValue(clusterDir);
0469:                                faketask.execute();
0470:                                break;
0471:                            }
0472:                        }
0473:                    }
0474:                    faketask.setName("cluster.dir");
0475:                    faketask.setValue("extra"); // fallback
0476:                    faketask.execute();
0477:                    faketask.setName("netbeans.dest.dir");
0478:                    faketask.setValue(properties.get("netbeans.dest.dir"));
0479:                    faketask.execute();
0480:                    faketask.setName("cluster");
0481:                    faketask
0482:                            .setValue(fakeproj
0483:                                    .replaceProperties("${netbeans.dest.dir}/${cluster.dir}"));
0484:                    faketask.execute();
0485:                    break;
0486:                case ParseProjectXml.TYPE_SUITE:
0487:                    assert path == null;
0488:                    faketask.setName("suite.dir");
0489:                    faketask.setValue(properties.get("suite.dir"));
0490:                    faketask.execute();
0491:                    faketask.setName("cluster");
0492:                    faketask.setValue(fakeproj
0493:                            .replaceProperties("${suite.dir}/build/cluster"));
0494:                    faketask.execute();
0495:                    break;
0496:                case ParseProjectXml.TYPE_STANDALONE:
0497:                    assert path == null;
0498:                    faketask.setName("cluster");
0499:                    faketask.setValue(fakeproj
0500:                            .replaceProperties("${basedir}/build/cluster"));
0501:                    faketask.execute();
0502:                    break;
0503:                default:
0504:                    assert false : moduleType;
0505:                }
0506:                File jar = fakeproj.resolveFile(fakeproj
0507:                        .replaceProperties("${cluster}/${module.jar}"));
0508:                List<File> exts = new ArrayList<File>();
0509:                for (Element ext : XMLUtil.findSubElements(dataEl)) {
0510:                    if (!ext.getLocalName().equals("class-path-extension")) {
0511:                        continue;
0512:                    }
0513:                    Element binaryOrigin = ParseProjectXml.findNBMElement(ext,
0514:                            "binary-origin");
0515:                    File origBin = null;
0516:                    if (binaryOrigin != null) {
0517:                        String reltext = XMLUtil.findText(binaryOrigin);
0518:                        String nball = properties.get("nb_all");
0519:                        if (nball != null) {
0520:                            faketask.setName("nb_all");
0521:                            faketask.setValue(nball);
0522:                            faketask.execute();
0523:                        }
0524:                        fakeproj.setBaseDir(dir);
0525:                        origBin = fakeproj.resolveFile(fakeproj
0526:                                .replaceProperties(reltext));
0527:                    }
0528:
0529:                    File resultBin = null;
0530:                    if (origBin == null || !origBin.exists()) {
0531:                        Element runtimeRelativePath = ParseProjectXml
0532:                                .findNBMElement(ext, "runtime-relative-path");
0533:                        if (runtimeRelativePath == null) {
0534:                            throw new IOException(
0535:                                    "Have malformed <class-path-extension> in "
0536:                                            + projectxml);
0537:                        }
0538:                        String reltext = XMLUtil.findText(runtimeRelativePath);
0539:                        // No need to evaluate property refs in it - it is *not* substitutable-text in the schema.
0540:                        resultBin = new File(jar.getParentFile(), reltext
0541:                                .replace('/', File.separatorChar));
0542:                    }
0543:
0544:                    if (origBin != null) {
0545:                        exts.add(origBin);
0546:                    }
0547:
0548:                    if (resultBin != null) {
0549:                        exts.add(resultBin);
0550:                    }
0551:                }
0552:                List<String> prereqs = new ArrayList<String>();
0553:                List<String> rundeps = new ArrayList<String>();
0554:                Element depsEl = ParseProjectXml.findNBMElement(dataEl,
0555:                        "module-dependencies");
0556:                if (depsEl == null) {
0557:                    throw new IOException("Malformed project file "
0558:                            + projectxml);
0559:                }
0560:                Element testDepsEl = ParseProjectXml.findNBMElement(dataEl,
0561:                        "test-dependencies");
0562:                //compileDeps = Collections.emptyList();
0563:                String compileTestDeps[] = null;
0564:                if (testDepsEl != null) {
0565:                    for (Element depssEl : XMLUtil.findSubElements(testDepsEl)) {
0566:                        String testtype = ParseProjectXml.findTextOrNull(
0567:                                depssEl, "name");
0568:
0569:                        if (testtype == null || testtype.equals("unit")) {
0570:                            List<String> compileDepsList = new ArrayList<String>();
0571:                            for (Element dep : XMLUtil.findSubElements(depssEl)) {
0572:                                if (dep.getTagName().equals("test-dependency")) {
0573:                                    if (ParseProjectXml.findNBMElement(dep,
0574:                                            "test") != null) {
0575:                                        compileDepsList.add(ParseProjectXml
0576:                                                .findTextOrNull(dep,
0577:                                                        "code-name-base"));
0578:                                    }
0579:                                }
0580:                            }
0581:                            compileTestDeps = new String[compileDepsList.size()];
0582:                            compileDepsList.toArray(compileTestDeps);
0583:                        }
0584:
0585:                    }
0586:                }
0587:                for (Element dep : XMLUtil.findSubElements(depsEl)) {
0588:                    Element cnbEl2 = ParseProjectXml.findNBMElement(dep,
0589:                            "code-name-base");
0590:                    if (cnbEl2 == null) {
0591:                        throw new IOException("Malformed project file "
0592:                                + projectxml);
0593:                    }
0594:                    String cnb2 = XMLUtil.findText(cnbEl2);
0595:                    rundeps.add(cnb2);
0596:                    if (ParseProjectXml.findNBMElement(dep,
0597:                            "build-prerequisite") == null) {
0598:                        continue;
0599:                    }
0600:                    prereqs.add(cnb2);
0601:                }
0602:                String cluster = fakeproj.getProperty("cluster.dir"); // may be null
0603:                Entry entry = new Entry(cnb, jar, exts.toArray(new File[exts
0604:                        .size()]), dir, path, prereqs
0605:                        .toArray(new String[prereqs.size()]), cluster, rundeps
0606:                        .toArray(new String[rundeps.size()]), compileTestDeps);
0607:                if (entries.containsKey(cnb)) {
0608:                    throw new IOException("Duplicated module " + cnb
0609:                            + ": found in " + entries.get(cnb) + " and "
0610:                            + entry);
0611:                } else {
0612:                    entries.put(cnb, entry);
0613:                }
0614:                return true;
0615:            }
0616:
0617:            static String abbreviate(String cnb) {
0618:                return cnb.replaceFirst("^org\\.netbeans\\.modules\\.", ""). // NOI18N
0619:                        replaceFirst(
0620:                                "^org\\.netbeans\\.(libs|lib|api|spi|core)\\.",
0621:                                "$1."). // NOI18N
0622:                        replaceFirst("^org\\.netbeans\\.", "o.n."). // NOI18N
0623:                        replaceFirst("^org\\.openide\\.", "openide."). // NOI18N
0624:                        replaceFirst("^org\\.", "o."). // NOI18N
0625:                        replaceFirst("^com\\.sun\\.", "c.s."). // NOI18N
0626:                        replaceFirst("^com\\.", "c."); // NOI18N
0627:            }
0628:
0629:            /**
0630:             * Find all modules in a binary build, possibly from cache.
0631:             */
0632:            private static Map<String, Entry> scanBinaries(
0633:                    Hashtable<String, String> properties, Project project)
0634:                    throws IOException {
0635:                String buildS = properties.get("netbeans.dest.dir");
0636:                File basedir = new File(properties.get("basedir"));
0637:                if (buildS == null) {
0638:                    throw new IOException(
0639:                            "No definition of netbeans.dest.dir in " + basedir);
0640:                }
0641:                // Resolve against basedir, and normalize ../ sequences and so on in case they are used.
0642:                // Neither operation is likely to be needed, but just in case.
0643:                File build = FileUtils.getFileUtils().normalize(
0644:                        FileUtils.getFileUtils().resolveFile(basedir, buildS)
0645:                                .getAbsolutePath());
0646:                if (!build.isDirectory()) {
0647:                    throw new IOException("No such netbeans.dest.dir: " + build);
0648:                }
0649:                Map<String, Entry> entries = BINARY_SCAN_CACHE.get(build);
0650:                if (entries == null) {
0651:                    if (project != null) {
0652:                        project.log("Scanning for modules in " + build);
0653:                    }
0654:                    entries = new HashMap<String, Entry>();
0655:                    doScanBinaries(build, entries);
0656:                    if (project != null) {
0657:                        project.log("Found modules: " + entries.keySet(),
0658:                                Project.MSG_VERBOSE);
0659:                    }
0660:                    BINARY_SCAN_CACHE.put(build, entries);
0661:                }
0662:                return entries;
0663:            }
0664:
0665:            private static final String[] MODULE_DIRS = { "modules",
0666:                    "modules/eager", "modules/autoload", "lib", "core", };
0667:
0668:            /**
0669:             * Look for all possible modules in a NB build.
0670:             * Checks modules/{,autoload/,eager/}*.jar as well as well-known core/*.jar and lib/boot.jar in each cluster.
0671:             * XXX would be slightly more precise to check config/Modules/*.xml rather than scan for module JARs.
0672:             */
0673:            private static void doScanBinaries(File build,
0674:                    Map<String, Entry> entries) throws IOException {
0675:                File[] clusters = build.listFiles();
0676:                if (clusters == null) {
0677:                    throw new IOException("Cannot examine dir " + build);
0678:                }
0679:                for (int i = 0; i < clusters.length; i++) {
0680:                    for (int j = 0; j < MODULE_DIRS.length; j++) {
0681:                        File dir = new File(clusters[i], MODULE_DIRS[j]
0682:                                .replace('/', File.separatorChar));
0683:                        if (!dir.isDirectory()) {
0684:                            continue;
0685:                        }
0686:                        File[] jars = dir.listFiles();
0687:                        if (jars == null) {
0688:                            throw new IOException("Cannot examine dir " + dir);
0689:                        }
0690:                        for (int k = 0; k < jars.length; k++) {
0691:                            File m = jars[k];
0692:                            if (!m.getName().endsWith(".jar")) {
0693:                                continue;
0694:                            }
0695:                            JarFile jf = new JarFile(m);
0696:                            try {
0697:                                Attributes attr = jf.getManifest()
0698:                                        .getMainAttributes();
0699:                                String codename = attr
0700:                                        .getValue("OpenIDE-Module");
0701:                                if (codename == null) {
0702:                                    continue;
0703:                                }
0704:                                String codenamebase;
0705:                                int slash = codename.lastIndexOf('/');
0706:                                if (slash == -1) {
0707:                                    codenamebase = codename;
0708:                                } else {
0709:                                    codenamebase = codename.substring(0, slash);
0710:                                }
0711:
0712:                                String cp = attr.getValue("Class-Path");
0713:                                File[] exts;
0714:                                if (cp == null) {
0715:                                    exts = new File[0];
0716:                                } else {
0717:                                    String[] pieces = cp.split(" +");
0718:                                    exts = new File[pieces.length];
0719:                                    for (int l = 0; l < pieces.length; l++) {
0720:                                        exts[l] = new File(dir, pieces[l]
0721:                                                .replace('/',
0722:                                                        File.separatorChar));
0723:                                    }
0724:                                }
0725:                                String moduleDependencies = attr
0726:                                        .getValue("OpenIDE-Module-Module-Dependencies");
0727:
0728:                                Entry entry = new Entry(
0729:                                        codenamebase,
0730:                                        m,
0731:                                        exts,
0732:                                        dir,
0733:                                        null,
0734:                                        null,
0735:                                        clusters[i].getName(),
0736:                                        parseRuntimeDependencies(moduleDependencies),
0737:                                        null);
0738:                                if (entries.containsKey(codenamebase)) {
0739:                                    throw new IOException("Duplicated module "
0740:                                            + codenamebase + ": found in "
0741:                                            + entries.get(codenamebase)
0742:                                            + " and " + entry);
0743:                                } else {
0744:                                    entries.put(codenamebase, entry);
0745:                                }
0746:                            } finally {
0747:                                jf.close();
0748:                            }
0749:                        }
0750:                    }
0751:                }
0752:            }
0753:
0754:            private static Map<String, Entry> scanSuiteSources(
0755:                    Hashtable<String, String> properties, Project project)
0756:                    throws IOException {
0757:                File basedir = new File(properties.get("basedir"));
0758:                String suiteDir = properties.get("suite.dir");
0759:                if (suiteDir == null) {
0760:                    throw new IOException("No definition of suite.dir in "
0761:                            + basedir);
0762:                }
0763:                File suite = FileUtils.getFileUtils().resolveFile(basedir,
0764:                        suiteDir);
0765:                if (!suite.isDirectory()) {
0766:                    throw new IOException("No such suite " + suite);
0767:                }
0768:                Map<String, Entry> entries = SUITE_SCAN_CACHE.get(suite);
0769:                if (entries == null) {
0770:                    if (project != null) {
0771:                        project.log("Scanning for modules in suite " + suite);
0772:                    }
0773:                    entries = new HashMap<String, Entry>();
0774:                    doScanSuite(entries, suite, properties, project);
0775:                    if (project != null) {
0776:                        project.log("Found modules: " + entries.keySet(),
0777:                                Project.MSG_VERBOSE);
0778:                    }
0779:                    SUITE_SCAN_CACHE.put(suite, entries);
0780:                }
0781:                return entries;
0782:            }
0783:
0784:            private static void doScanSuite(Map<String, Entry> entries,
0785:                    File suite, Hashtable<String, String> properties,
0786:                    Project project) throws IOException {
0787:                Project fakeproj = new Project();
0788:                fakeproj.setBaseDir(suite); // in case ${basedir} is used somewhere
0789:                Property faketask = new Property();
0790:                faketask.setProject(fakeproj);
0791:                faketask.setFile(new File(suite,
0792:                        "nbproject/private/private.properties".replace('/',
0793:                                File.separatorChar)));
0794:                faketask.execute();
0795:                faketask.setFile(new File(suite, "nbproject/project.properties"
0796:                        .replace('/', File.separatorChar)));
0797:                faketask.execute();
0798:                String modulesS = fakeproj.getProperty("modules");
0799:                if (modulesS == null) {
0800:                    throw new IOException("No definition of modules in "
0801:                            + suite);
0802:                }
0803:                String[] modules = Path.translatePath(fakeproj, modulesS);
0804:                for (int i = 0; i < modules.length; i++) {
0805:                    File module = new File(modules[i]);
0806:                    if (!module.isDirectory()) {
0807:                        throw new IOException("No such module " + module
0808:                                + " referred to from " + suite);
0809:                    }
0810:                    if (!scanPossibleProject(module, entries, properties, null,
0811:                            ParseProjectXml.TYPE_SUITE, project, null)) {
0812:                        throw new IOException("No valid module found in "
0813:                                + module + " referred to from " + suite);
0814:                    }
0815:                }
0816:            }
0817:
0818:            private static Entry scanStandaloneSource(
0819:                    Hashtable<String, String> properties, Project project)
0820:                    throws IOException {
0821:                if (properties.get("project") == null)
0822:                    return null; //Not a standalone module
0823:                File basedir = new File(properties.get("project"));
0824:                Entry entry = STANDALONE_SCAN_CACHE.get(basedir);
0825:                if (entry == null) {
0826:                    Map<String, Entry> entries = new HashMap<String, Entry>();
0827:                    if (!scanPossibleProject(basedir, entries, properties,
0828:                            null, ParseProjectXml.TYPE_STANDALONE, project,
0829:                            null)) {
0830:                        throw new IOException("No valid module found in "
0831:                                + basedir);
0832:                    }
0833:                    assert entries.size() == 1;
0834:                    entry = entries.values().iterator().next();
0835:                    STANDALONE_SCAN_CACHE.put(basedir, entry);
0836:                }
0837:                return entry;
0838:            }
0839:
0840:            /** all module entries, indexed by cnb */
0841:            private final Map<String, Entry> entries;
0842:
0843:            /**
0844:             * Initiates scan if not already parsed.
0845:             * Properties interpreted:
0846:             * <ol>
0847:             * <li> ${nb_all} - location of NB sources (used only for netbeans.org modules)
0848:             * <li> ${netbeans.dest.dir} - location of NB build
0849:             * <li> ${basedir} - directory of this project (used only for standalone modules)
0850:             * <li> ${suite.dir} - directory of the suite (used only for suite modules)
0851:             * <li> ${nb.cluster.TOKEN} - list of module paths included in cluster TOKEN (comma-separated) (used only for netbeans.org modules)
0852:             * <li> ${nb.cluster.TOKEN.dir} - directory in ${netbeans.dest.dir} where cluster TOKEN is built (used only for netbeans.org modules)
0853:             * <li> ${project} - basedir for standalone modules
0854:             * </ol>
0855:             * @param properties some properties to be used (see above)
0856:             * @param type the type of project
0857:             * @param project a project ref, only for logging (may be null with no loss of semantics)
0858:             */
0859:            public ModuleListParser(Hashtable<String, String> properties,
0860:                    int type, Project project) throws IOException {
0861:                String nball = properties.get("nb_all");
0862:                if (type != ParseProjectXml.TYPE_NB_ORG) {
0863:                    // External module.
0864:                    File basedir = new File(properties.get("basedir"));
0865:                    if (nball != null && project != null) {
0866:                        project
0867:                                .log(
0868:                                        "You must *not* declare <suite-component/> or <standalone/> for a netbeans.org module in "
0869:                                                + basedir
0870:                                                + "; fix project.xml to use the /2 schema",
0871:                                        Project.MSG_WARN);
0872:                    }
0873:                    entries = scanBinaries(properties, project);
0874:                    if (type == ParseProjectXml.TYPE_SUITE) {
0875:                        entries.putAll(scanSuiteSources(properties, project));
0876:                    } else {
0877:                        assert type == ParseProjectXml.TYPE_STANDALONE;
0878:                        Entry e = scanStandaloneSource(properties, project);
0879:                        entries.put(e.getCnb(), e);
0880:                    }
0881:                } else {
0882:                    // netbeans.org module.
0883:                    if (nball == null) {
0884:                        throw new IOException(
0885:                                "You must declare either <suite-component/> or <standalone/> for an external module in "
0886:                                        + new File(properties.get("basedir")));
0887:                    }
0888:                    // If scan.binaries property is set or it runs from tests we scan binaries otherwise sources.
0889:                    boolean xtest = properties.get("xtest.home") != null
0890:                            && properties.get("xtest.testtype") != null;
0891:                    if (properties.get("scan.binaries") != null || xtest) {
0892:                        entries = scanBinaries(properties, project);
0893:                        // module itself has to be added because it doesn't have to be in binaries
0894:                        Entry e = scanStandaloneSource(properties, project);
0895:                        if (e != null) {
0896:                            // xtest gets module jar and cluster from binaries
0897:                            if (e.clusterName == null && xtest) {
0898:                                Entry oldEntry = entries.get(e.getCnb());
0899:                                if (oldEntry != null) {
0900:                                    e = new Entry(e.getCnb(),
0901:                                            oldEntry.getJar(), e
0902:                                                    .getClassPathExtensions(),
0903:                                            e.sourceLocation,
0904:                                            e.netbeansOrgPath,
0905:                                            e.buildPrerequisites, oldEntry
0906:                                                    .getClusterName(),
0907:                                            e.runtimeDependencies, e
0908:                                                    .getTestDependencies());
0909:                                }
0910:                            }
0911:                            entries.put(e.getCnb(), e);
0912:                        }
0913:                        if (!xtest) {
0914:                            // to allow building of depend modules on top of binary
0915:                            entries.putAll(scanNetBeansOrgSources(new File(
0916:                                    nball), properties, project));
0917:                        }
0918:                    } else {
0919:                        entries = scanNetBeansOrgSources(new File(nball),
0920:                                properties, project);
0921:                    }
0922:                }
0923:            }
0924:
0925:            /**
0926:             * Find all entries in this list.
0927:             * @return a set of all known entries
0928:             */
0929:            public Set<Entry> findAll() {
0930:                return new HashSet<Entry>(entries.values());
0931:            }
0932:
0933:            /**
0934:             * Find one entry by code name base.
0935:             * @param cnb the desired code name base
0936:             * @return the matching entry or null
0937:             */
0938:            public Entry findByCodeNameBase(String cnb) {
0939:                return entries.get(cnb);
0940:            }
0941:
0942:            /** parse Openide-Module-Module-Dependencies entry
0943:             * @return array of code name bases
0944:             */
0945:            private static String[] parseRuntimeDependencies(
0946:                    String moduleDependencies) {
0947:                if (moduleDependencies == null) {
0948:                    return new String[0];
0949:                }
0950:                List<String> cnds = new ArrayList<String>();
0951:                StringTokenizer toks = new StringTokenizer(moduleDependencies,
0952:                        ",");
0953:                while (toks.hasMoreTokens()) {
0954:                    String token = toks.nextToken().trim();
0955:                    // substring cnd/x
0956:                    int slIdx = token.indexOf('/');
0957:                    if (slIdx != -1) {
0958:                        token = token.substring(0, slIdx);
0959:                    }
0960:                    // substring cnd' 'xx
0961:                    slIdx = token.indexOf(' ');
0962:                    if (slIdx != -1) {
0963:                        token = token.substring(0, slIdx);
0964:                    }
0965:                    // substring cnd > 
0966:                    slIdx = token.indexOf('>');
0967:                    if (slIdx != -1) {
0968:                        token = token.substring(0, slIdx);
0969:                    }
0970:                    token = token.trim();
0971:                    if (token.length() > 0) {
0972:                        cnds.add(token);
0973:                    }
0974:                }
0975:                return cnds.toArray(new String[cnds.size()]);
0976:            }
0977:
0978:            /**
0979:             * One entry in the file.
0980:             */
0981:            @SuppressWarnings("serial")
0982:            // really want it to be incompatible if format changes
0983:            public static final class Entry implements  Serializable {
0984:
0985:                // Synch with org.netbeans.modules.apisupport.project.universe.ModuleList:
0986:                private final String cnb;
0987:                private final File jar;
0988:                private final File[] classPathExtensions;
0989:                private final File sourceLocation;
0990:                private final String netbeansOrgPath;
0991:                private final String[] buildPrerequisites;
0992:                private final String clusterName;
0993:                private final String[] runtimeDependencies;
0994:                // dependencies on other tests
0995:                private final String[] testDependencies;
0996:
0997:                Entry(String cnb, File jar, File[] classPathExtensions,
0998:                        File sourceLocation, String netbeansOrgPath,
0999:                        String[] buildPrerequisites, String clusterName,
1000:                        String[] runtimeDependencies, String[] testDependencies) {
1001:                    this .cnb = cnb;
1002:                    this .jar = jar;
1003:                    this .classPathExtensions = classPathExtensions;
1004:                    this .sourceLocation = sourceLocation;
1005:                    this .netbeansOrgPath = netbeansOrgPath;
1006:                    this .buildPrerequisites = buildPrerequisites;
1007:                    this .clusterName = clusterName;
1008:                    this .runtimeDependencies = runtimeDependencies;
1009:                    this .testDependencies = testDependencies;
1010:                }
1011:
1012:                /**
1013:                 * Get the code name base, e.g. org.netbeans.modules.ant.grammar.
1014:                 */
1015:                public String getCnb() {
1016:                    return cnb;
1017:                }
1018:
1019:                /**
1020:                 * Get the absolute JAR location, e.g. .../ide5/modules/org-netbeans-modules-ant-grammar.jar.
1021:                 */
1022:                public File getJar() {
1023:                    return jar;
1024:                }
1025:
1026:                /**
1027:                 * Get a list of extensions to the class path of this module (may be empty).
1028:                 */
1029:                public File[] getClassPathExtensions() {
1030:                    return classPathExtensions;
1031:                }
1032:
1033:                /**
1034:                 * Get the path within netbeans.org, if this is a netbeans.org module (else null).
1035:                 */
1036:                public String getNetbeansOrgPath() {
1037:                    return netbeansOrgPath;
1038:                }
1039:
1040:                /**
1041:                 * Get a list of declared build prerequisites (or null for sourceless entries).
1042:                 * Each entry is a code name base.
1043:                 */
1044:                public String[] getBuildPrerequisites() {
1045:                    return buildPrerequisites;
1046:                }
1047:
1048:                /** Get runtime dependencies, OpenIDE-Module-Dependencies entry. 
1049:                 */
1050:                public String[] getRuntimeDependencies() {
1051:                    return runtimeDependencies;
1052:                }
1053:
1054:                /**
1055:                 * Return the name of the cluster in which this module resides.
1056:                 * If this entry represents an external module in source form,
1057:                 * then the cluster will be null. If the module represents a netbeans.org
1058:                 * module or a binary module in a platform, then the cluster name will
1059:                 * be the (base) name of the directory containing the "modules" subdirectory
1060:                 * (sometimes "lib" or "core") where the JAR is.
1061:                 */
1062:                public String getClusterName() {
1063:                    return clusterName;
1064:                }
1065:
1066:                public String[] getTestDependencies() {
1067:                    return testDependencies;
1068:                }
1069:
1070:                public @Override
1071:                String toString() {
1072:                    return (sourceLocation != null ? sourceLocation : jar)
1073:                            .getAbsolutePath();
1074:                }
1075:
1076:            }
1077:
1078:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.