Source Code Cross Referenced for ProjectLibraryProvider.java in  » IDE-Netbeans » project.ant » org » netbeans » modules » project » ant » 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 » project.ant » org.netbeans.modules.project.ant 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * The contents of this file are subject to the terms of the Common Development
0003:         * and Distribution License (the License). You may not use this file except in
0004:         * compliance with the License.
0005:         *
0006:         * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
0007:         * or http://www.netbeans.org/cddl.txt.
0008:         *
0009:         * When distributing Covered Code, include this CDDL Header Notice in each file
0010:         * and include the License file at http://www.netbeans.org/cddl.txt.
0011:         * If applicable, add the following below the CDDL Header, with the fields
0012:         * enclosed by brackets [] replaced by your own identifying information:
0013:         * "Portions Copyrighted [year] [name of copyright owner]"
0014:         *
0015:         * The Original Software is NetBeans. The Initial Developer of the Original
0016:         * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
0017:         * Microsystems, Inc. All Rights Reserved.
0018:         */
0019:
0020:        package org.netbeans.modules.project.ant;
0021:
0022:        import java.beans.PropertyChangeEvent;
0023:        import java.beans.PropertyChangeListener;
0024:        import java.beans.PropertyChangeSupport;
0025:        import java.io.File;
0026:        import java.io.FileInputStream;
0027:        import java.io.IOException;
0028:        import java.io.InputStream;
0029:        import java.io.OutputStream;
0030:        import java.lang.ref.Reference;
0031:        import java.lang.ref.WeakReference;
0032:        import java.net.MalformedURLException;
0033:        import java.net.URISyntaxException;
0034:        import java.net.URL;
0035:        import java.util.ArrayList;
0036:        import java.util.Arrays;
0037:        import java.util.Collections;
0038:        import java.util.HashMap;
0039:        import java.util.HashSet;
0040:        import java.util.List;
0041:        import java.util.Map;
0042:        import java.util.Properties;
0043:        import java.util.Set;
0044:        import java.util.logging.Logger;
0045:        import java.util.regex.Matcher;
0046:        import java.util.regex.Pattern;
0047:        import javax.swing.JFileChooser;
0048:        import javax.swing.event.ChangeListener;
0049:        import javax.swing.filechooser.FileFilter;
0050:        import org.netbeans.api.project.Project;
0051:        import org.netbeans.api.project.ProjectManager;
0052:        import org.netbeans.api.project.libraries.Library;
0053:        import org.netbeans.api.project.libraries.LibraryManager;
0054:        import org.netbeans.api.project.ui.OpenProjects;
0055:        import org.netbeans.api.queries.CollocationQuery;
0056:        import org.netbeans.api.queries.SharabilityQuery;
0057:        import org.netbeans.spi.project.AuxiliaryConfiguration;
0058:        import org.netbeans.spi.project.libraries.ArealLibraryProvider;
0059:        import org.netbeans.spi.project.libraries.LibraryImplementation;
0060:        import org.netbeans.spi.project.libraries.LibraryProvider;
0061:        import org.netbeans.spi.project.libraries.LibraryStorageArea;
0062:        import org.netbeans.spi.project.libraries.support.LibrariesSupport;
0063:        import org.netbeans.spi.project.support.ant.AntProjectEvent;
0064:        import org.netbeans.spi.project.support.ant.AntProjectHelper;
0065:        import org.netbeans.spi.project.support.ant.AntProjectListener;
0066:        import org.netbeans.spi.project.support.ant.EditableProperties;
0067:        import org.netbeans.spi.project.support.ant.PropertyProvider;
0068:        import org.netbeans.spi.project.support.ant.PropertyUtils;
0069:        import org.netbeans.spi.queries.SharabilityQueryImplementation;
0070:        import org.openide.filesystems.FileObject;
0071:        import org.openide.filesystems.FileUtil;
0072:        import org.openide.filesystems.URLMapper;
0073:        import org.openide.util.ChangeSupport;
0074:        import org.openide.util.Exceptions;
0075:        import org.openide.util.Mutex;
0076:        import org.openide.util.MutexException;
0077:        import org.openide.util.NbBundle;
0078:        import org.openide.util.NbCollections;
0079:        import org.openide.util.RequestProcessor;
0080:        import org.openide.util.Utilities;
0081:        import org.openide.util.WeakListeners;
0082:        import org.openide.xml.XMLUtil;
0083:        import org.w3c.dom.Document;
0084:        import org.w3c.dom.Element;
0085:
0086:        /**
0087:         * Supplier of libraries declared in open projects.
0088:         * @see "issue #44035"
0089:         */
0090:        public class ProjectLibraryProvider
0091:                implements 
0092:                ArealLibraryProvider<ProjectLibraryProvider.ProjectLibraryArea, ProjectLibraryProvider.ProjectLibraryImplementation>,
0093:                PropertyChangeListener, AntProjectListener {
0094:
0095:            private static final String NAMESPACE = "http://www.netbeans.org/ns/ant-project-libraries/1"; // NOI18N
0096:            private static final String EL_LIBRARIES = "libraries"; // NOI18N
0097:            private static final String EL_DEFINITIONS = "definitions"; // NOI18N
0098:
0099:            private final PropertyChangeSupport pcs = new PropertyChangeSupport(
0100:                    this );
0101:            private AntProjectListener apl;
0102:
0103:            public static ProjectLibraryProvider INSTANCE;
0104:
0105:            private volatile boolean listening = true;
0106:            private final Map<ProjectLibraryArea, Reference<LP>> providers = new HashMap<ProjectLibraryArea, Reference<LP>>();
0107:
0108:            /**
0109:             * Default constructor for lookup.
0110:             */
0111:            public ProjectLibraryProvider() {
0112:                INSTANCE = this ;
0113:            }
0114:
0115:            public Class<ProjectLibraryArea> areaType() {
0116:                return ProjectLibraryArea.class;
0117:            }
0118:
0119:            public Class<ProjectLibraryImplementation> libraryType() {
0120:                return ProjectLibraryImplementation.class;
0121:            }
0122:
0123:            @Override
0124:            public String toString() {
0125:                return "ProjectLibraryProvider"; // NOI18N
0126:            }
0127:
0128:            // ---- management of areas ----
0129:
0130:            public void addPropertyChangeListener(
0131:                    PropertyChangeListener listener) {
0132:                pcs.addPropertyChangeListener(listener);
0133:            }
0134:
0135:            public void removePropertyChangeListener(
0136:                    PropertyChangeListener listener) {
0137:                pcs.removePropertyChangeListener(listener);
0138:            }
0139:
0140:            public Set<ProjectLibraryArea> getOpenAreas() {
0141:                synchronized (this ) { // lazy init of OpenProjects-related stuff is better for unit testing
0142:                    if (apl == null) {
0143:                        apl = WeakListeners.create(AntProjectListener.class,
0144:                                this , null);
0145:                        OpenProjects.getDefault().addPropertyChangeListener(
0146:                                WeakListeners.propertyChange(this , OpenProjects
0147:                                        .getDefault()));
0148:                    }
0149:                }
0150:                Set<ProjectLibraryArea> areas = new HashSet<ProjectLibraryArea>();
0151:                for (Project p : OpenProjects.getDefault().getOpenProjects()) {
0152:                    AntProjectHelper helper = AntBasedProjectFactorySingleton
0153:                            .getHelperFor(p);
0154:                    if (helper == null) {
0155:                        // Not an Ant-based project; ignore.
0156:                        continue;
0157:                    }
0158:                    helper.removeAntProjectListener(apl);
0159:                    helper.addAntProjectListener(apl);
0160:                    Definitions def = findDefinitions(helper);
0161:                    if (def != null) {
0162:                        areas
0163:                                .add(new ProjectLibraryArea(
0164:                                        def.mainPropertiesFile));
0165:                    }
0166:                }
0167:                return areas;
0168:            }
0169:
0170:            public ProjectLibraryArea createArea() {
0171:                JFileChooser jfc = new JFileChooser();
0172:                jfc.setApproveButtonText(NbBundle.getMessage(
0173:                        ProjectLibraryProvider.class,
0174:                        "ProjectLibraryProvider.open_or_create"));
0175:                FileFilter filter = new FileFilter() {
0176:                    public boolean accept(File f) {
0177:                        return f.isDirectory()
0178:                                || (f.getName().endsWith(".properties") && !f
0179:                                        .getName().endsWith(
0180:                                                "-private.properties")); // NOI18N
0181:                    }
0182:
0183:                    public String getDescription() {
0184:                        return NbBundle.getMessage(
0185:                                ProjectLibraryProvider.class,
0186:                                "ProjectLibraryProvider.properties_files");
0187:                    }
0188:                };
0189:                jfc.setFileFilter(filter);
0190:                FileUtil.preventFileChooserSymlinkTraversal(jfc, null); // XXX remember last-selected dir
0191:                while (jfc.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
0192:                    File f = jfc.getSelectedFile();
0193:                    if (filter.accept(f)) {
0194:                        return new ProjectLibraryArea(f);
0195:                    }
0196:                    // Else bad filename, reopen dialog. XXX would be better to just disable OK button, but not sure how...?
0197:                }
0198:                return null;
0199:            }
0200:
0201:            public ProjectLibraryArea loadArea(URL location) {
0202:                if (location.getProtocol().equals("file")
0203:                        && location.getPath().endsWith(".properties")) { // NOI18N
0204:                    try {
0205:                        return new ProjectLibraryArea(
0206:                                new File(location.toURI()));
0207:                    } catch (URISyntaxException x) {
0208:                        Exceptions.printStackTrace(x);
0209:                    }
0210:                }
0211:                return null;
0212:            }
0213:
0214:            public void propertyChange(PropertyChangeEvent ev) {
0215:                if (OpenProjects.PROPERTY_OPEN_PROJECTS.equals(ev
0216:                        .getPropertyName())) {
0217:                    pcs.firePropertyChange(
0218:                            ArealLibraryProvider.PROP_OPEN_AREAS, null, null);
0219:                }
0220:            }
0221:
0222:            public void configurationXmlChanged(AntProjectEvent ev) {
0223:                pcs.firePropertyChange(ArealLibraryProvider.PROP_OPEN_AREAS,
0224:                        null, null);
0225:            }
0226:
0227:            public void propertiesChanged(AntProjectEvent ev) {
0228:            }
0229:
0230:            // ---- management of libraries ----
0231:
0232:            private final class LP implements 
0233:                    LibraryProvider<ProjectLibraryImplementation>,
0234:                    FileChangeSupportListener {
0235:
0236:                private final ProjectLibraryArea area;
0237:                private final PropertyChangeSupport pcs = new PropertyChangeSupport(
0238:                        this );
0239:                private final Map<String, ProjectLibraryImplementation> libraries;
0240:
0241:                LP(ProjectLibraryArea area) {
0242:                    this .area = area;
0243:                    libraries = calculate(area);
0244:                    Definitions defs = new Definitions(area.mainPropertiesFile);
0245:                    FileChangeSupport.DEFAULT.addListener(this ,
0246:                            defs.mainPropertiesFile);
0247:                    FileChangeSupport.DEFAULT.addListener(this ,
0248:                            defs.privatePropertiesFile);
0249:                }
0250:
0251:                public synchronized ProjectLibraryImplementation[] getLibraries() {
0252:                    return libraries.values().toArray(
0253:                            new ProjectLibraryImplementation[libraries.size()]);
0254:                }
0255:
0256:                ProjectLibraryImplementation getLibrary(String name) {
0257:                    return libraries.get(name);
0258:                }
0259:
0260:                public void addPropertyChangeListener(
0261:                        PropertyChangeListener listener) {
0262:                    pcs.addPropertyChangeListener(listener);
0263:                }
0264:
0265:                public void removePropertyChangeListener(
0266:                        PropertyChangeListener listener) {
0267:                    pcs.removePropertyChangeListener(listener);
0268:                }
0269:
0270:                public void fileCreated(FileChangeSupportEvent event) {
0271:                    recalculate();
0272:                }
0273:
0274:                public void fileDeleted(FileChangeSupportEvent event) {
0275:                    recalculate();
0276:                }
0277:
0278:                public void fileModified(FileChangeSupportEvent event) {
0279:                    recalculate();
0280:                }
0281:
0282:                private void recalculate() {
0283:                    boolean fire;
0284:                    Map<ProjectLibraryImplementation, List<String>> toFire = new HashMap<ProjectLibraryImplementation, List<String>>();
0285:                    synchronized (this ) {
0286:                        fire = delta(libraries, calculate(area), toFire);
0287:                    }
0288:                    //#128784, don't fire in synchronized block..
0289:                    if (toFire.size() > 0) {
0290:                        for (ProjectLibraryImplementation impl : toFire
0291:                                .keySet()) {
0292:                            for (String prop : toFire.get(impl)) {
0293:                                impl.pcs.firePropertyChange(prop, null, null);
0294:                            }
0295:                        }
0296:                    }
0297:                    if (fire) {
0298:                        pcs.firePropertyChange(LibraryProvider.PROP_LIBRARIES,
0299:                                null, null);
0300:                    }
0301:                }
0302:
0303:            }
0304:
0305:            public synchronized LP getLibraries(ProjectLibraryArea area) {
0306:                Reference<LP> rlp = providers.get(area);
0307:                LP lp = rlp != null ? rlp.get() : null;
0308:                if (lp == null) {
0309:                    lp = new LP(area);
0310:                    providers.put(area, new WeakReference<LP>(lp));
0311:                }
0312:                return lp;
0313:            }
0314:
0315:            public ProjectLibraryImplementation createLibrary(String type,
0316:                    String name, ProjectLibraryArea area,
0317:                    Map<String, List<URL>> contents) throws IOException {
0318:                File f = area.mainPropertiesFile;
0319:                assert listening;
0320:                listening = false;
0321:                try {
0322:                    if (type.equals("j2se")) { // NOI18N
0323:                        replaceProperty(f, true, "libs." + name + ".classpath",
0324:                                ""); // NOI18N
0325:                    } else {
0326:                        replaceProperty(f, false, "libs." + name + ".type",
0327:                                type); // NOI18N
0328:                    }
0329:                } finally {
0330:                    listening = true;
0331:                }
0332:                LP lp = getLibraries(area);
0333:                boolean fire = delta(
0334:                        lp.libraries,
0335:                        calculate(area),
0336:                        new HashMap<ProjectLibraryImplementation, List<String>>());
0337:                ProjectLibraryImplementation impl = lp.getLibrary(name);
0338:                assert impl != null : name + " not found in " + f;
0339:                for (Map.Entry<String, List<URL>> entry : contents.entrySet()) {
0340:                    impl.setContent(entry.getKey(), entry.getValue());
0341:                }
0342:                if (fire) {
0343:                    lp.pcs.firePropertyChange(LibraryProvider.PROP_LIBRARIES,
0344:                            null, null);
0345:                }
0346:                return impl;
0347:            }
0348:
0349:            public void remove(ProjectLibraryImplementation pli)
0350:                    throws IOException {
0351:                String prefix = "libs." + pli.name + "."; // NOI18N
0352:                // XXX run atomically to fire changes just once:
0353:                for (File f : new File[] { pli.mainPropertiesFile,
0354:                        pli.privatePropertiesFile }) {
0355:                    for (String k : loadProperties(f).keySet()) {
0356:                        if (k.startsWith(prefix)) {
0357:                            replaceProperty(f, false, k);
0358:                        }
0359:                    }
0360:                }
0361:            }
0362:
0363:            /** one definitions entry */
0364:            private static final class Definitions {
0365:                /** may or may not exist; in case you need to listen to it */
0366:                final File mainPropertiesFile;
0367:                /** similar to {@link #mainPropertiesFile} but for *-private.properties; null if main is not *.properties */
0368:                final File privatePropertiesFile;
0369:                private Map<String, String> properties;
0370:
0371:                Definitions(File mainPropertiesFile) {
0372:                    this .mainPropertiesFile = mainPropertiesFile;
0373:                    String suffix = ".properties"; // NOI18N
0374:                    String name = mainPropertiesFile.getName();
0375:                    if (name.endsWith(suffix)) {
0376:                        privatePropertiesFile = new File(mainPropertiesFile
0377:                                .getParentFile(), name.substring(0, name
0378:                                .length()
0379:                                - suffix.length())
0380:                                + "-private" + suffix); // NOI18N
0381:                    } else {
0382:                        privatePropertiesFile = null;
0383:                    }
0384:                }
0385:
0386:                /** with ${base} resolved according to resolveBase; may be empty or have junk defs */
0387:                synchronized Map<String, String> properties(boolean resolveBase) {
0388:                    if (properties == null) {
0389:                        properties = new HashMap<String, String>();
0390:                        String basedir = mainPropertiesFile.getParent();
0391:                        for (Map.Entry<String, String> entry : loadProperties(
0392:                                mainPropertiesFile).entrySet()) {
0393:                            String value = entry.getValue();
0394:                            if (resolveBase) {
0395:                                value = value.replace("${base}", basedir); // NOI18N
0396:                            }
0397:                            properties.put(entry.getKey(), value.replace('/',
0398:                                    File.separatorChar));
0399:                        }
0400:                        if (privatePropertiesFile != null) {
0401:                            for (Map.Entry<String, String> entry : loadProperties(
0402:                                    privatePropertiesFile).entrySet()) {
0403:                                String value = entry.getValue();
0404:                                if (resolveBase) {
0405:                                    value = value.replace("${base}", basedir); // NOI18N
0406:                                }
0407:                                properties.put(entry.getKey(), value.replace(
0408:                                        '/', File.separatorChar));
0409:                            }
0410:                        }
0411:                    }
0412:                    return properties;
0413:                }
0414:            }
0415:
0416:            private static Definitions findDefinitions(AntProjectHelper helper) {
0417:                String text = getLibrariesLocationText(helper
0418:                        .createAuxiliaryConfiguration());
0419:                if (text != null) {
0420:                    File mainPropertiesFile = helper.resolveFile(text);
0421:                    if (mainPropertiesFile.getName().endsWith(".properties")) { // NOI18N
0422:                        return new Definitions(mainPropertiesFile);
0423:                    }
0424:                }
0425:                return null;
0426:            }
0427:
0428:            public static File getLibrariesLocation(AuxiliaryConfiguration aux,
0429:                    File projectFolder) {
0430:                String text = getLibrariesLocationText(aux);
0431:                if (text != null) {
0432:                    return PropertyUtils.resolveFile(projectFolder, text);
0433:                }
0434:                return null;
0435:            }
0436:
0437:            /**
0438:             * Returns libraries location as text.
0439:             */
0440:            public static String getLibrariesLocationText(
0441:                    AuxiliaryConfiguration aux) {
0442:                Element libraries = aux.getConfigurationFragment(EL_LIBRARIES,
0443:                        NAMESPACE, true);
0444:                if (libraries != null) {
0445:                    for (Element definitions : Util.findSubElements(libraries)) {
0446:                        assert definitions.getLocalName()
0447:                                .equals(EL_DEFINITIONS) : definitions;
0448:                        String text = Util.findText(definitions);
0449:                        assert text != null : aux;
0450:                        return text;
0451:                    }
0452:                }
0453:                return null;
0454:            }
0455:
0456:            private static Map<String, String> loadProperties(File f) {
0457:                if (!f.isFile()) {
0458:                    return Collections.emptyMap();
0459:                }
0460:                Properties p = new Properties();
0461:                try {
0462:                    InputStream is = new FileInputStream(f);
0463:                    try {
0464:                        p.load(is);
0465:                    } finally {
0466:                        is.close();
0467:                    }
0468:                    return NbCollections.checkedMapByFilter(p, String.class,
0469:                            String.class, true);
0470:                } catch (IOException x) {
0471:                    Exceptions.attachMessage(x, "Loading: " + f); // NOI18N
0472:                    Exceptions.printStackTrace(x);
0473:                    return Collections.emptyMap();
0474:                }
0475:            }
0476:
0477:            //non private for test usage
0478:            static final Pattern LIBS_LINE = Pattern
0479:                    .compile("libs\\.([^${}]+)\\.([^${}.]+)"); // NOI18N
0480:
0481:            private static Map<String, ProjectLibraryImplementation> calculate(
0482:                    ProjectLibraryArea area) {
0483:                Map<String, ProjectLibraryImplementation> libs = new HashMap<String, ProjectLibraryImplementation>();
0484:                Definitions def = new Definitions(area.mainPropertiesFile);
0485:                Map<String, Map<String, String>> data = new HashMap<String, Map<String, String>>();
0486:                for (Map.Entry<String, String> entry : def.properties(false)
0487:                        .entrySet()) {
0488:                    Matcher match = LIBS_LINE.matcher(entry.getKey());
0489:                    if (!match.matches()) {
0490:                        continue;
0491:                    }
0492:                    String name = match.group(1);
0493:                    Map<String, String> subdata = data.get(name);
0494:                    if (subdata == null) {
0495:                        subdata = new HashMap<String, String>();
0496:                        data.put(name, subdata);
0497:                    }
0498:                    subdata.put(match.group(2), entry.getValue());
0499:                }
0500:                for (Map.Entry<String, Map<String, String>> entry : data
0501:                        .entrySet()) {
0502:                    String name = entry.getKey();
0503:                    String type = "j2se"; // NOI18N
0504:                    String description = null;
0505:                    Map<String, List<URL>> contents = new HashMap<String, List<URL>>();
0506:                    for (Map.Entry<String, String> subentry : entry.getValue()
0507:                            .entrySet()) {
0508:                        String k = subentry.getKey();
0509:                        if (k.equals("type")) { // NOI18N
0510:                            type = subentry.getValue();
0511:                        } else if (k.equals("name")) { // NOI18N
0512:                            // XXX currently overriding display name is not supported
0513:                        } else if (k.equals("description")) { // NOI18N
0514:                            description = subentry.getValue();
0515:                        } else {
0516:                            String[] path = PropertyUtils.tokenizePath(subentry
0517:                                    .getValue());
0518:                            List<URL> volume = new ArrayList<URL>(path.length);
0519:                            for (String component : path) {
0520:                                String jarFolder = null;
0521:                                // "!/" was replaced in def.properties() with "!"+File.separatorChar
0522:                                int index = component.indexOf("!"
0523:                                        + File.separatorChar); //NOI18N
0524:                                if (index != -1) {
0525:                                    jarFolder = component.substring(index + 2);
0526:                                    component = component.substring(0, index);
0527:                                }
0528:                                String f = component.replace('/',
0529:                                        File.separatorChar).replace('\\',
0530:                                        File.separatorChar).replace(
0531:                                        "${base}" + File.separatorChar, "");
0532:                                File normalizedFile = FileUtil
0533:                                        .normalizeFile(new File(component
0534:                                                .replace('/',
0535:                                                        File.separatorChar)
0536:                                                .replace('\\',
0537:                                                        File.separatorChar)
0538:                                                .replace(
0539:                                                        "${base}",
0540:                                                        area.mainPropertiesFile
0541:                                                                .getParent())));
0542:                                try {
0543:                                    URL u = LibrariesSupport
0544:                                            .convertFilePathToURL(f);
0545:                                    if (FileUtil.isArchiveFile(normalizedFile
0546:                                            .toURI().toURL())) {
0547:                                        u = FileUtil.getArchiveRoot(u);
0548:                                        if (jarFolder != null) {
0549:                                            u = appendJarFolder(u, jarFolder);
0550:                                        }
0551:                                    } else if (!u.toExternalForm()
0552:                                            .endsWith("/")) {
0553:                                        u = new URL(u.toExternalForm() + "/");
0554:                                    }
0555:                                    volume.add(u);
0556:                                } catch (MalformedURLException x) {
0557:                                    Exceptions.printStackTrace(x);
0558:                                }
0559:                            }
0560:                            contents.put(k, volume);
0561:                        }
0562:                    }
0563:                    libs.put(name, new ProjectLibraryImplementation(
0564:                            def.mainPropertiesFile, def.privatePropertiesFile,
0565:                            type, name, description, contents));
0566:                }
0567:                return libs;
0568:            }
0569:
0570:            private boolean delta(
0571:                    Map<String, ProjectLibraryImplementation> libraries,
0572:                    Map<String, ProjectLibraryImplementation> newLibraries,
0573:                    Map<ProjectLibraryImplementation, List<String>> toFire) {
0574:                if (!listening) {
0575:                    return false;
0576:                }
0577:                assert toFire != null;
0578:                Set<String> added = new HashSet<String>(newLibraries.keySet());
0579:                added.removeAll(libraries.keySet());
0580:                Set<String> removed = new HashSet<String>();
0581:                for (Map.Entry<String, ProjectLibraryImplementation> entry : libraries
0582:                        .entrySet()) {
0583:                    String name = entry.getKey();
0584:                    ProjectLibraryImplementation old = entry.getValue();
0585:                    ProjectLibraryImplementation nue = newLibraries.get(name);
0586:                    if (nue == null) {
0587:                        removed.add(name);
0588:                        continue;
0589:                    }
0590:                    if (!old.type.equals(nue.type)) {
0591:                        // Cannot fire this.
0592:                        added.add(name);
0593:                        removed.add(name);
0594:                        libraries.put(name, nue);
0595:                        continue;
0596:                    }
0597:                    assert old.name.equals(nue.name);
0598:                    if (!Utilities.compareObjects(old.description,
0599:                            nue.description)) {
0600:                        old.description = nue.description;
0601:                        List<String> props = toFire.get(old);
0602:                        if (props == null) {
0603:                            props = new ArrayList<String>();
0604:                            toFire.put(old, props);
0605:                        }
0606:                        props.add(LibraryImplementation.PROP_DESCRIPTION);
0607:                    }
0608:                    if (!old.contents.equals(nue.contents)) {
0609:                        old.contents = nue.contents;
0610:                        List<String> props = toFire.get(old);
0611:                        if (props == null) {
0612:                            props = new ArrayList<String>();
0613:                            toFire.put(old, props);
0614:                        }
0615:                        props.add(LibraryImplementation.PROP_CONTENT);
0616:                    }
0617:                }
0618:                for (String name : added) {
0619:                    libraries.put(name, newLibraries.get(name));
0620:                }
0621:                for (String name : removed) {
0622:                    libraries.remove(name);
0623:                }
0624:                return !added.isEmpty() || !removed.isEmpty();
0625:            }
0626:
0627:            /** for jar url this method returns path wihtin jar or null*/
0628:            private static String getJarFolder(URL url) {
0629:                assert "jar".equals(url.getProtocol()) : url;
0630:                String u = url.toExternalForm();
0631:                int index = u.indexOf("!/"); //NOI18N
0632:                if (index != -1 && index + 2 < u.length()) {
0633:                    return u.substring(index + 2);
0634:                }
0635:                return null;
0636:            }
0637:
0638:            /** append path to given jar root url */
0639:            private static URL appendJarFolder(URL u, String jarFolder) {
0640:                assert "jar".equals(u.getProtocol())
0641:                        && u.toExternalForm().endsWith("!/") : u;
0642:                try {
0643:                    return new URL(u + jarFolder.replace('\\', '/')); //NOI18N
0644:                } catch (MalformedURLException e) {
0645:                    throw new AssertionError(e);
0646:                }
0647:            }
0648:
0649:            static final class ProjectLibraryImplementation implements 
0650:                    LibraryImplementation {
0651:
0652:                final File mainPropertiesFile, privatePropertiesFile;
0653:                final String type;
0654:                String name;
0655:                String description;
0656:                Map<String, List<URL>> contents;
0657:                final PropertyChangeSupport pcs = new PropertyChangeSupport(
0658:                        this );
0659:
0660:                ProjectLibraryImplementation(File mainPropertiesFile,
0661:                        File privatePropertiesFile, String type, String name,
0662:                        String description, Map<String, List<URL>> contents) {
0663:                    this .mainPropertiesFile = mainPropertiesFile;
0664:                    this .privatePropertiesFile = privatePropertiesFile;
0665:                    this .type = type;
0666:                    this .name = name;
0667:                    this .description = description;
0668:                    this .contents = contents;
0669:                }
0670:
0671:                public String getType() {
0672:                    return type;
0673:                }
0674:
0675:                public String getName() {
0676:                    return name;
0677:                }
0678:
0679:                public String getDescription() {
0680:                    return description;
0681:                }
0682:
0683:                public String getLocalizingBundle() {
0684:                    return null;
0685:                }
0686:
0687:                public List<URL> getContent(String volumeType)
0688:                        throws IllegalArgumentException {
0689:                    List<URL> content = contents.get(volumeType);
0690:                    if (content == null) {
0691:                        content = Collections.emptyList();
0692:                    }
0693:                    return content;
0694:                }
0695:
0696:                public void setName(String name) {
0697:                    this .name = name;
0698:                    pcs.firePropertyChange(LibraryImplementation.PROP_NAME,
0699:                            null, null);
0700:                    throw new UnsupportedOperationException(); // XXX will anyone call this?
0701:                }
0702:
0703:                public void setDescription(String text) {
0704:                    throw new UnsupportedOperationException(); // XXX will anyone call this?
0705:                }
0706:
0707:                public void setContent(String volumeType, List<URL> path)
0708:                        throws IllegalArgumentException {
0709:                    if (path.equals(getContent(volumeType))) {
0710:                        return;
0711:                    }
0712:                    contents.put(volumeType, new ArrayList<URL>(path));
0713:                    List<String> value = new ArrayList<String>();
0714:                    for (URL entry : path) {
0715:                        String jarFolder = null;
0716:                        if ("jar".equals(entry.getProtocol())) { // NOI18N
0717:                            jarFolder = getJarFolder(entry);
0718:                            entry = FileUtil.getArchiveFile(entry);
0719:                        } else if (!"file".equals(entry.getProtocol())) { // NOI18N
0720:                            value.add(entry.toString());
0721:                            Logger
0722:                                    .getLogger(
0723:                                            ProjectLibraryProvider.class
0724:                                                    .getName())
0725:                                    .fine(
0726:                                            "Setting url="
0727:                                                    + entry
0728:                                                    + " as content for library volume type: "
0729:                                                    + volumeType);
0730:                            continue;
0731:                        }
0732:                        String p = LibrariesSupport.convertURLToFilePath(entry);
0733:                        File f = new File(p);
0734:                        // store properties always separated by '/' for consistency
0735:                        StringBuilder s = new StringBuilder();
0736:                        if (f.isAbsolute()) {
0737:                            s.append(f.getAbsolutePath().replace('\\', '/')); //NOI18N
0738:                        } else {
0739:                            s.append("${base}/" + p.replace('\\', '/')); // NOI18N
0740:                        }
0741:                        if (jarFolder != null) {
0742:                            s.append("!/"); // NOI18N
0743:                            s.append(jarFolder);
0744:                        }
0745:                        if (value.size() + 1 != path.size()) {
0746:                            s.append(File.pathSeparatorChar);
0747:                        }
0748:                        value.add(s.toString());
0749:                    }
0750:                    String key = "libs." + name + "." + volumeType; // NOI18N
0751:                    try {
0752:                        replaceProperty(mainPropertiesFile, true, key, value
0753:                                .toArray(new String[value.size()]));
0754:                    } catch (IOException x) {
0755:                        throw new IllegalArgumentException(x);
0756:                    }
0757:                    pcs.firePropertyChange(LibraryImplementation.PROP_CONTENT,
0758:                            null, null);
0759:                }
0760:
0761:                public void setLocalizingBundle(String resourceName) {
0762:                    throw new UnsupportedOperationException();
0763:                }
0764:
0765:                public void addPropertyChangeListener(PropertyChangeListener l) {
0766:                    pcs.addPropertyChangeListener(l);
0767:                }
0768:
0769:                public void removePropertyChangeListener(
0770:                        PropertyChangeListener l) {
0771:                    pcs.removePropertyChangeListener(l);
0772:                }
0773:
0774:                @Override
0775:                public String toString() {
0776:                    return "ProjectLibraryImplementation[name=" + name
0777:                            + ",file=" + mainPropertiesFile + ",contents="
0778:                            + contents + "]"; // NOI18N
0779:                }
0780:
0781:            }
0782:
0783:            private static void replaceProperty(File propfile,
0784:                    boolean classPathLikeValue, String key, String... value)
0785:                    throws IOException {
0786:                EditableProperties ep = new EditableProperties();
0787:                if (propfile.isFile()) {
0788:                    InputStream is = new FileInputStream(propfile);
0789:                    try {
0790:                        ep.load(is);
0791:                    } finally {
0792:                        is.close();
0793:                    }
0794:                }
0795:                if (Utilities.compareObjects(value, ep.getProperty(key))) {
0796:                    return;
0797:                }
0798:                if (value.length > 0) {
0799:                    if (classPathLikeValue) {
0800:                        ep.setProperty(key, value);
0801:                    } else {
0802:                        assert value.length == 1 : Arrays.asList(value);
0803:                        ep.setProperty(key, value[0]);
0804:                    }
0805:                } else {
0806:                    ep.remove(key);
0807:                }
0808:                FileObject fo = FileUtil.createData(propfile);
0809:                OutputStream os = fo.getOutputStream();
0810:                try {
0811:                    ep.store(os);
0812:                } finally {
0813:                    os.close();
0814:                }
0815:            }
0816:
0817:            static final class ProjectLibraryArea implements  LibraryStorageArea {
0818:
0819:                final File mainPropertiesFile;
0820:
0821:                ProjectLibraryArea(File mainPropertiesFile) {
0822:                    assert mainPropertiesFile.getName().endsWith(".properties") : mainPropertiesFile;
0823:                    this .mainPropertiesFile = mainPropertiesFile;
0824:                }
0825:
0826:                public String getDisplayName() {
0827:                    return mainPropertiesFile.getAbsolutePath();
0828:                }
0829:
0830:                public URL getLocation() {
0831:                    try {
0832:                        return mainPropertiesFile.toURI().toURL();
0833:                    } catch (MalformedURLException x) {
0834:                        throw new AssertionError(x);
0835:                    }
0836:                }
0837:
0838:                public boolean equals(Object obj) {
0839:                    return obj instanceof  ProjectLibraryArea
0840:                            && ((ProjectLibraryArea) obj).mainPropertiesFile
0841:                                    .equals(mainPropertiesFile);
0842:                }
0843:
0844:                public int hashCode() {
0845:                    return mainPropertiesFile.hashCode();
0846:                }
0847:
0848:                @Override
0849:                public String toString() {
0850:                    return "ProjectLibraryArea[" + mainPropertiesFile + "]"; // NOI18N
0851:                }
0852:
0853:            }
0854:
0855:            /**
0856:             * Used from {@link AntProjectHelper#getProjectLibrariesPropertyProvider}.
0857:             * @param helper a project
0858:             * @return a provider of project library definition properties
0859:             */
0860:            public static PropertyProvider createPropertyProvider(
0861:                    final AntProjectHelper helper) {
0862:                class PP implements  PropertyProvider,
0863:                        FileChangeSupportListener, AntProjectListener {
0864:                    final ChangeSupport cs = new ChangeSupport(this );
0865:                    final Set<File> listeningTo = new HashSet<File>();
0866:                    {
0867:                        helper.addAntProjectListener(WeakListeners.create(
0868:                                AntProjectListener.class, this , helper));
0869:                    }
0870:
0871:                    private void listenTo(File f, Set<File> noLongerListeningTo) {
0872:                        if (f != null) {
0873:                            noLongerListeningTo.remove(f);
0874:                            if (listeningTo.add(f)) {
0875:                                FileChangeSupport.DEFAULT.addListener(this , f);
0876:                            }
0877:                        }
0878:                    }
0879:
0880:                    public synchronized Map<String, String> getProperties() {
0881:                        Map<String, String> m = new HashMap<String, String>();
0882:                        // XXX add an AntProjectListener
0883:                        Set<File> noLongerListeningTo = new HashSet<File>(
0884:                                listeningTo);
0885:                        Definitions def = findDefinitions(helper);
0886:                        if (def != null) {
0887:                            m.putAll(def.properties(true));
0888:                            listenTo(def.mainPropertiesFile,
0889:                                    noLongerListeningTo);
0890:                            listenTo(def.privatePropertiesFile,
0891:                                    noLongerListeningTo);
0892:                        }
0893:                        for (File f : noLongerListeningTo) {
0894:                            listeningTo.remove(f);
0895:                            FileChangeSupport.DEFAULT.removeListener(this , f);
0896:                        }
0897:                        return m;
0898:                    }
0899:
0900:                    public void addChangeListener(ChangeListener l) {
0901:                        cs.addChangeListener(l);
0902:                    }
0903:
0904:                    public void removeChangeListener(ChangeListener l) {
0905:                        cs.removeChangeListener(l);
0906:                    }
0907:
0908:                    public void fileCreated(FileChangeSupportEvent event) {
0909:                        fireChangeNowOrLater();
0910:                    }
0911:
0912:                    public void fileDeleted(FileChangeSupportEvent event) {
0913:                        fireChangeNowOrLater();
0914:                    }
0915:
0916:                    public void fileModified(FileChangeSupportEvent event) {
0917:                        fireChangeNowOrLater();
0918:                    }
0919:
0920:                    void fireChangeNowOrLater() {
0921:                        // See PropertyUtils.FilePropertyProvider.
0922:                        if (!cs.hasListeners()) {
0923:                            return;
0924:                        }
0925:                        final Mutex.Action<Void> action = new Mutex.Action<Void>() {
0926:                            public Void run() {
0927:                                cs.fireChange();
0928:                                return null;
0929:                            }
0930:                        };
0931:                        if (ProjectManager.mutex().isWriteAccess()
0932:                                || FIRE_CHANGES_SYNCH) {
0933:                            ProjectManager.mutex().readAccess(action);
0934:                        } else if (ProjectManager.mutex().isReadAccess()) {
0935:                            action.run();
0936:                        } else {
0937:                            RP.post(new Runnable() {
0938:                                public void run() {
0939:                                    ProjectManager.mutex().readAccess(action);
0940:                                }
0941:                            });
0942:                        }
0943:                    }
0944:
0945:                    public void configurationXmlChanged(AntProjectEvent ev) {
0946:                        cs.fireChange();
0947:                    }
0948:
0949:                    public void propertiesChanged(AntProjectEvent ev) {
0950:                    }
0951:                }
0952:                return new PP();
0953:            }
0954:
0955:            private static final RequestProcessor RP = new RequestProcessor(
0956:                    "ProjectLibraryProvider.RP"); // NOI18N
0957:            public static boolean FIRE_CHANGES_SYNCH = false; // used by tests
0958:
0959:            /**
0960:             * Is this library reachable from this project? Returns true if given library
0961:             * is defined in libraries location associated with this project.
0962:             */
0963:            public static boolean isReachableLibrary(Library library,
0964:                    AntProjectHelper helper) {
0965:                URL location = library.getManager().getLocation();
0966:                if (location == null) {
0967:                    return false;
0968:                }
0969:                ProjectLibraryArea area = INSTANCE.loadArea(location);
0970:                if (area == null) {
0971:                    return false;
0972:                }
0973:                ProjectLibraryImplementation pli = INSTANCE.getLibraries(area)
0974:                        .getLibrary(library.getName());
0975:                if (pli == null) {
0976:                    return false;
0977:                }
0978:                Definitions def = findDefinitions(helper);
0979:                if (def == null) {
0980:                    return false;
0981:                }
0982:                return def.mainPropertiesFile.equals(pli.mainPropertiesFile);
0983:            }
0984:
0985:            /**
0986:             * Create element for shared libraries to store in project.xml.
0987:             * 
0988:             * @param doc XML document
0989:             * @param location project relative or absolute OS path; cannot be null
0990:             * @return element
0991:             */
0992:            public static Element createLibrariesElement(Document doc,
0993:                    String location) {
0994:                Element libraries = doc
0995:                        .createElementNS(NAMESPACE, EL_LIBRARIES);
0996:                libraries.appendChild(
0997:                        libraries.getOwnerDocument().createElementNS(NAMESPACE,
0998:                                EL_DEFINITIONS)).appendChild(
0999:                        libraries.getOwnerDocument().createTextNode(location));
1000:                return libraries;
1001:            }
1002:
1003:            /**
1004:             * Used from {@link ReferenceHelper#getProjectLibraryManager}.
1005:             */
1006:            public static LibraryManager getProjectLibraryManager(
1007:                    AntProjectHelper helper) {
1008:                Definitions defs = findDefinitions(helper);
1009:                if (defs != null) {
1010:                    try {
1011:                        return LibraryManager
1012:                                .forLocation(defs.mainPropertiesFile.toURI()
1013:                                        .toURL());
1014:                    } catch (MalformedURLException x) {
1015:                        Exceptions.printStackTrace(x);
1016:                    }
1017:                }
1018:                return null;
1019:            }
1020:
1021:            /**
1022:             * Stores given libraries location in given project.
1023:             */
1024:            public static void setLibrariesLocation(AntProjectHelper helper,
1025:                    String librariesDefinition) {
1026:                //TODO do we need to create new auxiliary configuration instance? feels like a hack, we should be
1027:                // using the one from the project's lookup.  
1028:                if (librariesDefinition == null) {
1029:                    helper.createAuxiliaryConfiguration()
1030:                            .removeConfigurationFragment(EL_LIBRARIES,
1031:                                    NAMESPACE, true);
1032:                    return;
1033:                }
1034:                Element libraries = helper
1035:                        .createAuxiliaryConfiguration()
1036:                        .getConfigurationFragment(EL_LIBRARIES, NAMESPACE, true);
1037:                if (libraries == null) {
1038:                    libraries = XMLUtil.createDocument("dummy", null, null,
1039:                            null).createElementNS(NAMESPACE, EL_LIBRARIES); // NOI18N
1040:                } else {
1041:                    List<Element> elements = Util.findSubElements(libraries);
1042:                    if (elements.size() == 1) {
1043:                        libraries.removeChild(elements.get(0));
1044:                    }
1045:                }
1046:                libraries.appendChild(
1047:                        libraries.getOwnerDocument().createElementNS(NAMESPACE,
1048:                                EL_DEFINITIONS)).appendChild(
1049:                        libraries.getOwnerDocument().createTextNode(
1050:                                librariesDefinition));
1051:                helper.createAuxiliaryConfiguration().putConfigurationFragment(
1052:                        libraries, true);
1053:            }
1054:
1055:            /**
1056:             * Used from {@link org.netbeans.spi.project.support.ant.SharabilityQueryImpl}.
1057:             */
1058:            public static List<String> getUnsharablePathsWithinProject(
1059:                    AntProjectHelper helper) {
1060:                List<String> paths = new ArrayList<String>();
1061:                Definitions defs = findDefinitions(helper);
1062:                if (defs != null) {
1063:                    if (defs.privatePropertiesFile != null) {
1064:                        paths.add(defs.privatePropertiesFile.getAbsolutePath());
1065:                    }
1066:                }
1067:                return paths;
1068:            }
1069:
1070:            public static final class SharabilityQueryImpl implements 
1071:                    SharabilityQueryImplementation {
1072:
1073:                /** Default constructor for lookup. */
1074:                public SharabilityQueryImpl() {
1075:                }
1076:
1077:                public int getSharability(File file) {
1078:                    if (file.getName().endsWith("-private.properties")) { // NOI18N
1079:                        return SharabilityQuery.NOT_SHARABLE;
1080:                    } else {
1081:                        return SharabilityQuery.UNKNOWN;
1082:                    }
1083:                }
1084:
1085:            }
1086:
1087:            /**
1088:             * Used from {@link org.netbeans.spi.project.support.ant.ReferenceHelper}.
1089:             */
1090:            public static Library copyLibrary(final Library lib,
1091:                    final URL location, final boolean generateLibraryUniqueName)
1092:                    throws IOException {
1093:                assert LibrariesSupport.isAbsoluteURL(location);
1094:                final File libBaseFolder = new File(LibrariesSupport
1095:                        .convertURLToFilePath(location)).getParentFile();
1096:                FileObject sharedLibFolder;
1097:                try {
1098:                    sharedLibFolder = ProjectManager.mutex().writeAccess(
1099:                            new Mutex.ExceptionAction<FileObject>() {
1100:                                public FileObject run() throws IOException {
1101:                                    FileObject lf = FileUtil
1102:                                            .toFileObject(libBaseFolder);
1103:                                    if (lf == null) {
1104:                                        lf = FileUtil
1105:                                                .createFolder(libBaseFolder);
1106:                                    }
1107:                                    return lf.createFolder(getUniqueName(lf,
1108:                                            lib.getName(), null));
1109:                                }
1110:                            });
1111:                } catch (MutexException ex) {
1112:                    throw (IOException) ex.getException();
1113:                }
1114:                final Map<String, List<URL>> content = new HashMap<String, List<URL>>();
1115:                String[] volumes = LibrariesSupport.getLibraryTypeProvider(
1116:                        lib.getType()).getSupportedVolumeTypes();
1117:                for (String volume : volumes) {
1118:                    List<URL> volumeContent = new ArrayList<URL>();
1119:                    for (URL origlibEntry : lib.getContent(volume)) {
1120:                        URL libEntry = origlibEntry;
1121:                        String jarFolder = null;
1122:                        if ("jar".equals(libEntry.getProtocol())) { // NOI18N
1123:                            jarFolder = getJarFolder(libEntry);
1124:                            libEntry = FileUtil.getArchiveFile(libEntry);
1125:                        }
1126:                        FileObject libEntryFO = URLMapper
1127:                                .findFileObject(libEntry);
1128:                        if (libEntryFO == null) {
1129:                            if (!"file".equals(libEntry.getProtocol()) && // NOI18N
1130:                                    !"nbinst".equals(libEntry.getProtocol())) { // NOI18N
1131:                                Logger.getLogger(
1132:                                        ProjectLibraryProvider.class.getName())
1133:                                        .info(
1134:                                                "copyLibrary is ignoring entry "
1135:                                                        + libEntry);
1136:                                //this is probably exclusively urls to maven poms.
1137:                                continue;
1138:                            } else {
1139:                                Logger
1140:                                        .getLogger(
1141:                                                ProjectLibraryProvider.class
1142:                                                        .getName())
1143:                                        .warning(
1144:                                                "Library '"
1145:                                                        + lib.getDisplayName()
1146:                                                        + // NOI18N
1147:                                                        "' contains entry ("
1148:                                                        + libEntry
1149:                                                        + ") which does not exist. This entry is ignored and will not be copied to sharable libraries location."); // NOI18N
1150:                                continue;
1151:                            }
1152:                        }
1153:                        URL u;
1154:                        FileObject newFO;
1155:                        String name;
1156:                        if (CollocationQuery.areCollocated(libBaseFolder,
1157:                                FileUtil.toFile(libEntryFO))) {
1158:                            // if the jar/folder is in relation to the library folder (parent+child/same vcs)
1159:                            // don't replicate it but reference the original file.
1160:                            newFO = libEntryFO;
1161:                            name = PropertyUtils.relativizeFile(libBaseFolder,
1162:                                    FileUtil.toFile(newFO));
1163:                        } else {
1164:                            if (libEntryFO.isFolder()) {
1165:                                newFO = FileChooserAccessory
1166:                                        .copyFolderRecursively(libEntryFO,
1167:                                                sharedLibFolder);
1168:                                name = sharedLibFolder.getNameExt()
1169:                                        + File.separatorChar + newFO.getName()
1170:                                        + File.separatorChar;
1171:                            } else {
1172:                                String libEntryName = getUniqueName(
1173:                                        sharedLibFolder, libEntryFO.getName(),
1174:                                        libEntryFO.getExt());
1175:                                newFO = FileUtil.copyFile(libEntryFO,
1176:                                        sharedLibFolder, libEntryName);
1177:                                name = sharedLibFolder.getNameExt()
1178:                                        + File.separatorChar
1179:                                        + newFO.getNameExt();
1180:                            }
1181:                        }
1182:                        u = LibrariesSupport.convertFilePathToURL(name);
1183:                        if (FileUtil.isArchiveFile(newFO)) {
1184:                            u = FileUtil.getArchiveRoot(u);
1185:                        }
1186:                        if (jarFolder != null) {
1187:                            u = appendJarFolder(u, jarFolder);
1188:                        }
1189:                        volumeContent.add(u);
1190:                    }
1191:                    content.put(volume, volumeContent);
1192:                }
1193:                final LibraryManager man = LibraryManager.forLocation(location);
1194:                try {
1195:                    return ProjectManager.mutex().writeAccess(
1196:                            new Mutex.ExceptionAction<Library>() {
1197:                                public Library run() throws IOException {
1198:                                    String name = lib.getName();
1199:                                    if (generateLibraryUniqueName) {
1200:                                        int index = 2;
1201:                                        while (man.getLibrary(name) != null) {
1202:                                            name = lib.getName() + "-" + index;
1203:                                            index++;
1204:                                        }
1205:                                    }
1206:                                    return man.createLibrary(lib.getType(),
1207:                                            name, content);
1208:                                }
1209:                            });
1210:                } catch (MutexException ex) {
1211:                    throw (IOException) ex.getException();
1212:                }
1213:            }
1214:
1215:            /**
1216:             * Generate unique file name for the given folder, base name and optionally extension.
1217:             * @param baseFolder folder to generate new file name in
1218:             * @param nameFileName file name without extension
1219:             * @param extension can be null for folder
1220:             * @return new file name without extension
1221:             */
1222:            private static String getUniqueName(FileObject baseFolder,
1223:                    String nameFileName, String extension) {
1224:                assert baseFolder != null;
1225:                int suffix = 2;
1226:                String name = nameFileName; //NOI18N
1227:                while (baseFolder.getFileObject(name
1228:                        + (extension != null ? "." + extension : "")) != null) {
1229:                    name = nameFileName + "-" + suffix; // NOI18N
1230:                    suffix++;
1231:                }
1232:                return name;
1233:            }
1234:
1235:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.