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-2006 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.modules.mobility.project;
0043:
0044: import java.beans.PropertyChangeEvent;
0045: import java.beans.PropertyChangeListener;
0046: import java.beans.PropertyChangeSupport;
0047: import java.io.BufferedReader;
0048: import java.io.ByteArrayInputStream;
0049: import java.io.DataInputStream;
0050: import java.io.File;
0051: import java.io.IOException;
0052: import java.io.InputStream;
0053: import java.io.InputStreamReader;
0054: import java.net.URI;
0055: import java.net.URL;
0056: import java.net.URLConnection;
0057: import java.net.URLStreamHandler;
0058: import java.util.ArrayList;
0059: import java.util.Arrays;
0060: import java.util.Collection;
0061: import java.util.Collections;
0062: import java.util.Enumeration;
0063: import java.util.HashSet;
0064: import java.util.Iterator;
0065: import java.util.LinkedList;
0066: import java.util.List;
0067: import java.util.Map;
0068: import java.util.Properties;
0069: import java.util.Set;
0070: import java.util.TreeSet;
0071: import java.util.WeakHashMap;
0072: import javax.swing.Icon;
0073: import javax.swing.ImageIcon;
0074: import org.netbeans.api.mobility.project.PropertyDescriptor;
0075: import org.netbeans.api.project.FileOwnerQuery;
0076: import org.netbeans.api.project.Project;
0077: import org.netbeans.api.java.classpath.ClassPath;
0078: import org.netbeans.api.java.classpath.GlobalPathRegistry;
0079: import org.netbeans.api.java.platform.JavaPlatform;
0080: import org.netbeans.api.java.platform.JavaPlatformManager;
0081: import org.netbeans.api.java.platform.Specification;
0082: import org.netbeans.api.project.ProjectManager;
0083: import org.netbeans.api.project.ant.AntArtifact;
0084: import org.netbeans.api.java.project.JavaProjectConstants;
0085: import org.netbeans.modules.j2me.cdc.platform.spi.CDCPlatformConfigurator;
0086: import org.netbeans.modules.j2me.cdc.platform.spi.CDCPlatformUtil;
0087: import org.netbeans.spi.mobility.project.ProjectPropertiesDescriptor;
0088: import org.netbeans.spi.mobility.project.support.DefaultPropertyParsers;
0089: import org.netbeans.spi.mobility.project.ui.customizer.support.VisualPropertySupport;
0090: import org.netbeans.spi.project.ProjectConfiguration;
0091: import org.netbeans.api.project.ui.OpenProjects;
0092: import org.netbeans.modules.mobility.project.classpath.J2MEProjectClassPathExtender;
0093: import org.netbeans.spi.project.ui.ProjectOpenedHook;
0094: import org.openide.DialogDisplayer;
0095: import org.openide.NotifyDescriptor;
0096: import org.openide.filesystems.FileObject;
0097: import org.openide.filesystems.FileUtil;
0098: import org.openide.filesystems.Repository;
0099: import org.openide.loaders.DataFolder;
0100: import org.openide.loaders.DataObject;
0101: import org.openide.util.Lookup;
0102: import org.openide.util.Lookup.Result;
0103: import org.openide.util.RequestProcessor;
0104: import org.openide.util.WeakListeners;
0105: import org.openide.util.lookup.Lookups;
0106: import org.netbeans.modules.mobility.project.ui.J2MECustomizerProvider;
0107: import org.netbeans.modules.mobility.project.ui.J2MEPhysicalViewProvider;
0108: import org.netbeans.modules.mobility.project.queries.CompiledSourceForBinaryQuery;
0109: import org.netbeans.modules.mobility.project.queries.JavadocForBinaryQueryImpl;
0110: import org.netbeans.spi.project.AuxiliaryConfiguration;
0111: import org.netbeans.api.project.ProjectInformation;
0112: import org.netbeans.modules.j2me.cdc.platform.CDCPlatform;
0113: import org.netbeans.modules.mobility.project.classpath.J2MEClassPathProvider;
0114: import org.netbeans.modules.mobility.project.deployment.DeploymentPropertiesHandler;
0115: import org.netbeans.modules.mobility.project.deployment.MobilityDeploymentProperties;
0116: import org.netbeans.modules.mobility.project.queries.SourceLevelQueryImpl;
0117: import org.netbeans.modules.mobility.project.queries.FileBuiltQueryImpl;
0118: import org.netbeans.modules.mobility.project.queries.FileEncodingQueryImpl;
0119: import org.netbeans.modules.mobility.project.security.KeyStoreRepository;
0120: import org.netbeans.spi.java.project.support.ui.BrokenReferencesSupport;
0121: import org.netbeans.spi.mobility.deployment.DeploymentPlugin;
0122: import org.netbeans.spi.mobility.project.ProjectLookupProvider;
0123: import org.netbeans.spi.project.SubprojectProvider;
0124: import org.netbeans.spi.project.ant.AntArtifactProvider;
0125: import org.netbeans.spi.project.support.ant.*;
0126: import org.netbeans.spi.project.ui.RecommendedTemplates;
0127: import org.netbeans.spi.project.ui.PrivilegedTemplates;
0128: import org.openide.ErrorManager;
0129: import org.openide.modules.InstalledFileLocator;
0130: import org.openide.util.LookupEvent;
0131: import org.openide.util.LookupListener;
0132: import org.openide.util.Mutex;
0133: import org.openide.util.MutexException;
0134: import org.openide.util.NbBundle;
0135: import org.openide.util.Utilities;
0136: import org.w3c.dom.Element;
0137: import org.w3c.dom.NodeList;
0138: import org.w3c.dom.Text;
0139: import org.w3c.dom.Node;
0140:
0141: /**
0142: * Represents one plain J2ME project.
0143: * @author Jesse Glick, Adam Sotona
0144: */
0145: public final class J2MEProject implements Project, AntProjectListener {
0146:
0147: static final Icon J2ME_PROJECT_ICON = new ImageIcon(
0148: Utilities
0149: .loadImage("org/netbeans/modules/mobility/project/ui/resources/mobile-project.png")); // NOI18N
0150: private static final URLStreamHandler COMPOSED_STREAM_HANDLER = new URLStreamHandler() {
0151: protected URLConnection openConnection(URL u)
0152: throws IOException {
0153: return new ComposedConnection(u);
0154: }
0155: };
0156:
0157: static final String CONFIGS_NAME = "configurations"; // NOI18N
0158: static final String CONFIG_NAME = "configuration"; // NOI18N
0159: static final String CONFIGS_NS = "http://www.netbeans.org/ns/project-configurations/1"; // NOI18N
0160: static final String CLASSPATH = "classpath"; // NOI18N
0161:
0162: final AuxiliaryConfiguration aux;
0163: final AntProjectHelper helper;
0164: final GeneratedFilesHelper genFilesHelper;
0165: Lookup lookup;
0166: final MIDletsCacheHelper midletsCacheHelper;
0167: final ProjectConfigurationsHelper configHelper;
0168:
0169: private static final Set<FileObject> roots = new HashSet<FileObject>();
0170: private static final Map<FileObject, Boolean> folders = new WeakHashMap<FileObject, Boolean>();
0171: private final ReferenceHelper refHelper;
0172: private final PropertyChangeSupport pcs;
0173: public FileBuiltQueryImpl fileBuiltQuery;
0174:
0175: /* Side effect of this methosd is modification of fo - is this correct? */
0176: public static boolean isJ2MEFile(FileObject fo) {
0177: if (fo == null)
0178: return false;
0179: final FileObject archiveRoot = FileUtil.getArchiveFile(fo);
0180: if (archiveRoot != null) {
0181: fo = archiveRoot;
0182: }
0183: return isJ2MEFolder(fo.getParent());
0184: }
0185:
0186: private static boolean isJ2MEFolder(FileObject fo) {
0187: if (fo == null)
0188: return false;
0189: synchronized (roots) {
0190: if (roots.contains(fo))
0191: return true;
0192: }
0193: Boolean result;
0194: synchronized (folders) {
0195: result = folders.get(fo);
0196: }
0197: if (result == null) {
0198: FileObject xml;
0199: if (fo.isFolder()
0200: && (xml = fo.getFileObject("nbproject/project.xml")) != null) {
0201: result = isJ2MEProjectXML(xml);
0202: if (result)
0203: synchronized (roots) {
0204: roots.add(fo);
0205: }
0206: } else {
0207: result = isJ2MEFolder(fo.getParent());
0208: }
0209: synchronized (folders) {
0210: folders.put(fo, result);
0211: }
0212: }
0213: return result;
0214: }
0215:
0216: protected static void addRoots(final AntProjectHelper helper) {
0217: final String src = helper.getStandardPropertyEvaluator()
0218: .getProperty("src.dir"); //NOI18N
0219: if (src != null)
0220: addRoot(helper.resolveFileObject(src));
0221: }
0222:
0223: private static void addRoot(final FileObject fo) {
0224: if (fo != null && !isJ2MEFile(fo)) {
0225: synchronized (roots) {
0226: if (roots.add(fo))
0227: RequestProcessor.getDefault().post(new Runnable() {
0228: public void run() {
0229: final Enumeration en = fo.getChildren(true);
0230: while (en.hasMoreElements())
0231: try {
0232: final FileObject f2 = (FileObject) en
0233: .nextElement();
0234: if (f2.getExt().equals("java"))
0235: DataObject.find(f2).setValid(
0236: false); //NOI18N
0237: } catch (Exception e) {
0238: }
0239: }
0240: });
0241: }
0242: }
0243: }
0244:
0245: private static boolean isJ2MEProjectXML(final FileObject fo) {
0246: BufferedReader in = null;
0247: try {
0248: try {
0249: in = new BufferedReader(new InputStreamReader(fo
0250: .getInputStream()));
0251: String s;
0252: while ((s = in.readLine()) != null) {
0253: if (s.indexOf("<type>" + J2MEProjectType.TYPE
0254: + "</type>") >= 0)
0255: return true; //NOI18N
0256: }
0257: } finally {
0258: if (in != null)
0259: in.close();
0260: }
0261: } catch (IOException ioe) {
0262: }
0263: return false;
0264: }
0265:
0266: J2MEProject(AntProjectHelper helper) {
0267: this .helper = helper;
0268: addRoots(helper);
0269: aux = helper.createAuxiliaryConfiguration();
0270: refHelper = new ReferenceHelper(helper, aux, helper
0271: .getStandardPropertyEvaluator());
0272: configHelper = new ProjectConfigurationsHelper(helper, this );
0273: genFilesHelper = new GeneratedFilesHelper(helper);
0274: midletsCacheHelper = new MIDletsCacheHelper(helper,
0275: configHelper);
0276: helper.addAntProjectListener(new CDCMainClassHelper(helper));
0277: pcs = new PropertyChangeSupport(this );
0278: fileBuiltQuery = new FileBuiltQueryImpl(helper, configHelper);
0279: this .lookup = this .createLookup(aux);
0280: helper.addAntProjectListener(this );
0281: configHelper.addPropertyChangeListener(new TextSwitcher(this ,
0282: helper));
0283: }
0284:
0285: public void hookNewProjectCreated() {
0286: midletsCacheHelper.refresh();
0287: }
0288:
0289: public FileObject getProjectDirectory() {
0290: return helper.getProjectDirectory();
0291: }
0292:
0293: public Lookup getLookup() {
0294: return this .lookup;
0295: }
0296:
0297: public ProjectConfigurationsHelper getConfigurationHelper() {
0298: return configHelper;
0299: }
0300:
0301: private Lookup createLookup(final AuxiliaryConfiguration aux) {
0302: final SourcesHelper sourcesHelper = new SourcesHelper(helper,
0303: helper.getStandardPropertyEvaluator());
0304: sourcesHelper.addPrincipalSourceRoot("${src.dir}", NbBundle
0305: .getMessage(J2MEProject.class,
0306: "LBL_J2MEProject_Source_Packages"), /*XXX*/
0307: null, null); //NOI18N
0308: // XXX add build dir too?
0309: sourcesHelper.addTypedSourceRoot("${src.dir}",
0310: JavaProjectConstants.SOURCES_TYPE_JAVA, NbBundle
0311: .getMessage(J2MEProject.class,
0312: "LBL_J2MEProject_Source_Packages"), /*XXX*/
0313: null, null); //NOI18N
0314:
0315: final SubprojectProvider spp = refHelper
0316: .createSubprojectProvider();
0317:
0318: Object stdLookups[] = new Object[] {
0319: new Info(),
0320: aux,
0321: spp,
0322: new J2MEActionProvider(this , helper),
0323: new J2MEPhysicalViewProvider(this , helper, refHelper,
0324: configHelper),
0325: new J2MECustomizerProvider(this , helper, refHelper,
0326: configHelper),
0327: new J2MEClassPathProvider(helper),
0328: new CompiledSourceForBinaryQuery(this , helper),
0329: new AntArtifactProviderImpl(),
0330: new ProjectXmlSavedHookImpl(),
0331: new ProjectOpenedHookImpl(),
0332: new JavadocForBinaryQueryImpl(this , helper),
0333: helper.createSharabilityQuery(helper
0334: .getStandardPropertyEvaluator(),
0335: new String[] { "${src.dir}" }, new String[] {
0336: "${dist.root.dir}",
0337: "${build.root.dir}",
0338: "${deployment.copy.target}" }), //NOI18N
0339: configHelper,
0340: helper,
0341: sourcesHelper.createSources(),
0342: new RecommendedTemplatesImpl(),
0343: new SourceLevelQueryImpl(helper),
0344: midletsCacheHelper,
0345: fileBuiltQuery,
0346: refHelper,
0347: new J2MEProjectClassPathExtender(this , helper,
0348: refHelper, configHelper),
0349: new J2MEProjectOperations(this , helper, refHelper),
0350: new PreprocessorFileFilterImplementation(configHelper,
0351: helper), new FileEncodingQueryImpl(helper) };
0352: ArrayList<Object> list = new ArrayList<Object>();
0353: list.addAll(Arrays.asList(stdLookups));
0354: for (ProjectLookupProvider provider : Lookup.getDefault()
0355: .lookupAll(ProjectLookupProvider.class)) {
0356: list.addAll(provider.createLookupElements(this , helper,
0357: refHelper, configHelper));
0358: }
0359: return Lookups.fixed(list.toArray());
0360:
0361: }
0362:
0363: /** Store configured project name. */
0364: public void setName(final String name) {
0365: ProjectManager.mutex().writeAccess(new Mutex.Action<Object>() {
0366: public Object run() {
0367: final Element data = helper
0368: .getPrimaryConfigurationData(true);
0369: // XXX replace by XMLUtil when that has findElement, findText, etc.
0370: final NodeList nl = data
0371: .getElementsByTagNameNS(
0372: J2MEProjectType.PROJECT_CONFIGURATION_NAMESPACE,
0373: "name");
0374: Element nameEl;
0375: if (nl.getLength() == 1) {
0376: nameEl = (Element) nl.item(0);
0377: final NodeList deadKids = nameEl.getChildNodes();
0378: while (deadKids.getLength() > 0) {
0379: nameEl.removeChild(deadKids.item(0));
0380: }
0381: } else {
0382: nameEl = data
0383: .getOwnerDocument()
0384: .createElementNS(
0385: J2MEProjectType.PROJECT_CONFIGURATION_NAMESPACE,
0386: "name");
0387: data.insertBefore(nameEl, /* OK if null */data
0388: .getChildNodes().item(0));
0389: }
0390: nameEl.appendChild(data.getOwnerDocument()
0391: .createTextNode(name));
0392: helper.putPrimaryConfigurationData(data, true);
0393: return null;
0394: }
0395: });
0396: }
0397:
0398: public void addPropertyChangeListener(
0399: final PropertyChangeListener listener) {
0400: pcs.addPropertyChangeListener(listener);
0401: }
0402:
0403: public void removePropertyChangeListener(
0404: final PropertyChangeListener listener) {
0405: pcs.removePropertyChangeListener(listener);
0406: }
0407:
0408: public void configurationXmlChanged(final AntProjectEvent ev) {
0409: if (ev.getPath().equals(AntProjectHelper.PROJECT_XML_PATH)) {
0410: // Could be various kinds of changes, but name & displayName might have changed.
0411: final Info info = (Info) getLookup().lookup(
0412: ProjectInformation.class);
0413: info.firePropertyChange(ProjectInformation.PROP_NAME);
0414: info
0415: .firePropertyChange(ProjectInformation.PROP_DISPLAY_NAME);
0416: }
0417: }
0418:
0419: public void propertiesChanged(@SuppressWarnings("unused")
0420: final AntProjectEvent ev) {
0421: // currently ignored
0422: }
0423:
0424: protected void refreshPrivateProperties() throws IOException {
0425: try {
0426: ProjectManager.mutex().writeAccess(
0427: new Mutex.ExceptionAction<Object>() {
0428: public Object run() {
0429: boolean modified = false;
0430: EditableProperties proj = helper
0431: .getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH);
0432: EditableProperties priv = helper
0433: .getProperties(AntProjectHelper.PRIVATE_PROPERTIES_PATH);
0434: priv.setProperty("netbeans.user", System
0435: .getProperty("netbeans.user")); //NOI18N
0436: for (ProjectPropertiesDescriptor p : Lookup
0437: .getDefault()
0438: .lookup(
0439: new Lookup.Template<ProjectPropertiesDescriptor>(
0440: ProjectPropertiesDescriptor.class))
0441: .allInstances()) {
0442: for (PropertyDescriptor d : p
0443: .getPropertyDescriptors()) {
0444: if (d.getDefaultValue() != null) {
0445: EditableProperties ep = d
0446: .isShared() ? proj
0447: : priv;
0448: if (!ep
0449: .containsKey(d
0450: .getName())) {
0451: ep
0452: .setProperty(
0453: d.getName(),
0454: d
0455: .getDefaultValue());
0456: modified = true;
0457: }
0458: }
0459: }
0460: }
0461: Set<String> cfgs = removeConfigurationsFromProjectXml();
0462: if (!cfgs.isEmpty()) {
0463: modified = true;
0464: cfgs
0465: .addAll(Arrays
0466: .asList(proj
0467: .getProperty(
0468: DefaultPropertiesDescriptor.ALL_CONFIGURATIONS)
0469: .split(",")));
0470: cfgs.remove(" ");
0471: cfgs.remove(""); //NOI18N
0472: StringBuffer sb = new StringBuffer(" "); //NOI18N
0473: for (String s : cfgs) {
0474: sb.append(',').append(s);
0475: }
0476: proj
0477: .setProperty(
0478: DefaultPropertiesDescriptor.ALL_CONFIGURATIONS,
0479: sb.toString());
0480: }
0481: helper
0482: .putProperties(
0483: AntProjectHelper.PRIVATE_PROPERTIES_PATH,
0484: priv);
0485: if (modified)
0486: helper
0487: .putProperties(
0488: AntProjectHelper.PROJECT_PROPERTIES_PATH,
0489: proj);
0490: try {
0491: refHelper
0492: .addExtraBaseDirectory("netbeans.user"); //NOI18N
0493: } catch (IllegalArgumentException iae) {
0494: //ignore - see issue #102148
0495: }
0496: return null;
0497: }
0498: });
0499: } catch (MutexException e) {
0500: throw (IOException) e.getException();
0501: }
0502: // Probably unnecessary, but just in case:
0503: try {
0504: ProjectManager.getDefault().saveProject(J2MEProject.this );
0505: } catch (IOException e) {
0506: ErrorManager.getDefault().notify(e);
0507: }
0508: }
0509:
0510: private Set<String> removeConfigurationsFromProjectXml() {
0511: TreeSet<String> cfgs = new TreeSet();
0512: Element configs = aux.getConfigurationFragment(CONFIGS_NAME,
0513: CONFIGS_NS, true);
0514: if (configs != null) {
0515: try {
0516: NodeList subEls = configs.getElementsByTagNameNS(
0517: CONFIGS_NS, CONFIG_NAME);
0518: for (int i = 0; i < subEls.getLength(); i++) {
0519: final NodeList l = subEls.item(i).getChildNodes();
0520: for (int j = 0; j < l.getLength(); j++) {
0521: if (l.item(j).getNodeType() == Node.TEXT_NODE) {
0522: cfgs.add(((Text) l.item(j)).getNodeValue());
0523: }
0524: }
0525: }
0526: aux.removeConfigurationFragment(CONFIGS_NAME,
0527: CONFIGS_NS, true);
0528: } catch (IllegalArgumentException e) {
0529: ErrorManager.getDefault().notify(
0530: ErrorManager.INFORMATIONAL, e);
0531: }
0532:
0533: }
0534: return cfgs;
0535: }
0536:
0537: /**
0538: * Return configured project name.
0539: */
0540: public String getName() {
0541: return ProjectManager.mutex().readAccess(
0542: new Mutex.Action<String>() {
0543: public String run() {
0544: final Element data = helper
0545: .getPrimaryConfigurationData(true);
0546: // XXX replace by XMLUtil when that has findElement, findText, etc.
0547: NodeList nl = data
0548: .getElementsByTagNameNS(
0549: J2MEProjectType.PROJECT_CONFIGURATION_NAMESPACE,
0550: "name"); // NOI18N
0551: if (nl.getLength() == 1) {
0552: nl = nl.item(0).getChildNodes();
0553: if (nl.getLength() == 1
0554: && nl.item(0).getNodeType() == Node.TEXT_NODE) {
0555: return ((Text) nl.item(0))
0556: .getNodeValue();
0557: }
0558: }
0559: return "???"; // NOI18N
0560: }
0561: });
0562: }
0563:
0564: // Private innerclasses ----------------------------------------------------
0565:
0566: private final class ProjectXmlSavedHookImpl extends
0567: ProjectXmlSavedHook {
0568:
0569: ProjectXmlSavedHookImpl() {
0570: // Just to avoid creating accessor class
0571: }
0572:
0573: protected void projectXmlSaved() throws IOException {
0574: refreshBuildScripts(false);
0575: }
0576:
0577: }
0578:
0579: private final class ProjectOpenedHookImpl extends ProjectOpenedHook
0580: implements LookupListener {
0581:
0582: private boolean skipCloseHook = false;
0583: private PropertyChangeListener platformListener;
0584: private Lookup.Result deployments;
0585:
0586: //We need those listners to be able to check for changes on paltform bootclasspath
0587: private final class PlatformInstalledListener implements
0588: PropertyChangeListener {
0589: final List<JavaPlatform> knownPlatforms;
0590: private final PropertyChangeListener platformChange = new PropertyChangeListener() {
0591: public void propertyChange(PropertyChangeEvent evt) {
0592: if (CLASSPATH.equals(evt.getPropertyName())
0593: && evt.getSource() instanceof CDCPlatform) {
0594: CDCPlatform platform = (CDCPlatform) evt
0595: .getSource();
0596: if (platform != null) {
0597: List<ProjectConfiguration> configs = J2MEProject.this
0598: .getMatchingConfigs((String) platform
0599: .getProperties()
0600: .get("platform.ant.name"));
0601: J2MEProject.this
0602: .updateBootClassPathProperty(
0603: configs, platform);
0604: }
0605: }
0606: }
0607: };
0608:
0609: PlatformInstalledListener(JavaPlatform known[]) {
0610: knownPlatforms = new ArrayList(Arrays.asList(known));
0611:
0612: for (JavaPlatform plat : knownPlatforms) {
0613: plat.addPropertyChangeListener(platformChange);
0614: List<ProjectConfiguration> configs = J2MEProject.this
0615: .getMatchingConfigs(plat.getProperties()
0616: .get("platform.ant.name"));
0617: J2MEProject.this .updateBootClassPathProperty(
0618: configs, (CDCPlatform) plat);
0619: }
0620: }
0621:
0622: public void propertyChange(PropertyChangeEvent evt) {
0623: if (evt.getPropertyName().equals(
0624: JavaPlatformManager.PROP_INSTALLED_PLATFORMS)) {
0625: JavaPlatform[] known = JavaPlatformManager
0626: .getDefault().getPlatforms(
0627: null,
0628: new Specification(
0629: CDCPlatform.PLATFORM_CDC,
0630: null));
0631: List<JavaPlatform> list = Arrays.asList(known);
0632: List<JavaPlatform> added = new ArrayList(Arrays
0633: .asList(known));
0634: added.removeAll(knownPlatforms);
0635: knownPlatforms.removeAll(list);
0636: for (JavaPlatform platform : knownPlatforms) {
0637: platform
0638: .removePropertyChangeListener(platformChange);
0639: }
0640: for (JavaPlatform platform : added) {
0641: platform
0642: .addPropertyChangeListener(platformChange);
0643: }
0644: knownPlatforms.clear();
0645: knownPlatforms.addAll(list);
0646: }
0647: }
0648: };
0649:
0650: ProjectOpenedHookImpl() {
0651: // Just to avoid creating accessor class
0652: }
0653:
0654: protected synchronized void projectOpened() {
0655: //inicialize deployment plugins
0656: deployments = Lookup.getDefault().lookup(
0657: new Lookup.Template<DeploymentPlugin>(
0658: DeploymentPlugin.class));
0659: deployments.addLookupListener(this );
0660: resultChanged(new LookupEvent(deployments));
0661: //init keystore, safer than warmup
0662: KeyStoreRepository.getDefault();
0663: // Check up on build scripts.
0664: addRoots(helper);
0665: final SourcesHelper sourcesHelper = getLookup().lookup(
0666: SourcesHelper.class);
0667: final String srcDir = helper.getStandardPropertyEvaluator()
0668: .getProperty(DefaultPropertiesDescriptor.SRC_DIR);
0669: final FileObject srcRoot = srcDir == null ? null : helper
0670: .resolveFileObject(srcDir);
0671: final Project other = srcRoot == null ? null
0672: : FileOwnerQuery.getOwner(srcRoot);
0673: if (other != null && !J2MEProject.this .equals(other)) {
0674: if (Arrays.asList(
0675: OpenProjects.getDefault().getOpenProjects())
0676: .contains(other)) {
0677: final ProjectInformation pi = other.getLookup()
0678: .lookup(ProjectInformation.class);
0679: final String name = pi == null ? other
0680: .getProjectDirectory().getPath() : pi
0681: .getDisplayName();
0682: if (NotifyDescriptor.OK_OPTION
0683: .equals(DialogDisplayer
0684: .getDefault()
0685: .notify(
0686: new NotifyDescriptor.Confirmation(
0687: NbBundle
0688: .getMessage(
0689: J2MEProject.class,
0690: "MSG_ClashingSourceRoots",
0691: J2MEProject.this
0692: .getName(),
0693: name),
0694: NotifyDescriptor.OK_CANCEL_OPTION,
0695: NotifyDescriptor.WARNING_MESSAGE)))) { //NOI18N
0696: OpenProjects.getDefault().close(
0697: new Project[] { other });
0698: } else {
0699: skipCloseHook = true;
0700: OpenProjects.getDefault().close(
0701: new Project[] { J2MEProject.this });
0702: return;
0703: }
0704: }
0705: }
0706: ProjectManager.mutex().postWriteRequest(new Runnable() {
0707: public void run() {
0708: try {
0709: if (sourcesHelper != null)
0710: sourcesHelper
0711: .registerExternalRoots(FileOwnerQuery.EXTERNAL_ALGORITHM_TRANSIENT);
0712: } catch (IllegalStateException ise) {
0713: }
0714: if (srcRoot != null)
0715: FileOwnerQuery
0716: .markExternalOwner(
0717: srcRoot,
0718: J2MEProject.this ,
0719: FileOwnerQuery.EXTERNAL_ALGORITHM_TRANSIENT);
0720: }
0721: });
0722: try {
0723: refreshBuildScripts(true);
0724: refreshPrivateProperties();
0725: refreshBootClasspath();
0726: } catch (IOException e) {
0727: ErrorManager.getDefault().notify(
0728: ErrorManager.INFORMATIONAL, e);
0729: }
0730:
0731: // register project's classpaths to GlobalPathRegistry
0732: final J2MEClassPathProvider cpProvider = lookup
0733: .lookup(J2MEClassPathProvider.class);
0734: GlobalPathRegistry.getDefault().register(ClassPath.BOOT,
0735: new ClassPath[] { cpProvider.getBootClassPath() });
0736: GlobalPathRegistry.getDefault().register(ClassPath.SOURCE,
0737: new ClassPath[] { cpProvider.getSourcepath() });
0738: GlobalPathRegistry.getDefault().register(
0739: ClassPath.COMPILE,
0740: new ClassPath[] { cpProvider
0741: .getCompileTimeClasspath() });
0742:
0743: final J2MEPhysicalViewProvider phvp = lookup
0744: .lookup(J2MEPhysicalViewProvider.class);
0745: if (phvp.hasBrokenLinks()) {
0746: BrokenReferencesSupport.showAlert();
0747: }
0748:
0749: midletsCacheHelper.refresh();
0750: }
0751:
0752: protected synchronized void projectClosed() {
0753: if (skipCloseHook)
0754: return;
0755: //do not listen on deployments for this project
0756: deployments.removeLookupListener(this );
0757:
0758: // Probably unnecessary, but just in case:
0759: try {
0760: ProjectManager.getDefault().saveProject(
0761: J2MEProject.this );
0762: } catch (IOException e) {
0763: ErrorManager.getDefault().notify(e);
0764: }
0765:
0766: // unregister project's classpaths to GlobalPathRegistry
0767: final J2MEClassPathProvider cpProvider = lookup
0768: .lookup(J2MEClassPathProvider.class);
0769: GlobalPathRegistry.getDefault().unregister(ClassPath.BOOT,
0770: new ClassPath[] { cpProvider.getBootClassPath() });
0771: GlobalPathRegistry.getDefault().unregister(
0772: ClassPath.SOURCE,
0773: new ClassPath[] { cpProvider.getSourcepath() });
0774: GlobalPathRegistry.getDefault().unregister(
0775: ClassPath.COMPILE,
0776: new ClassPath[] { cpProvider
0777: .getCompileTimeClasspath() });
0778:
0779: JavaPlatformManager.getDefault()
0780: .removePropertyChangeListener(platformListener);
0781: }
0782:
0783: private void refreshBootClasspath() {
0784:
0785: JavaPlatform[] installedPlatforms = JavaPlatformManager
0786: .getDefault().getPlatforms(
0787: null,
0788: new Specification(CDCPlatform.PLATFORM_CDC,
0789: null)); //NOI18N
0790: platformListener = new PlatformInstalledListener(
0791: installedPlatforms);
0792: JavaPlatformManager.getDefault().addPropertyChangeListener(
0793: platformListener);
0794: }
0795:
0796: public void resultChanged(final LookupEvent e) {
0797: final Collection<Lookup.Result> result = ((Lookup.Result) e
0798: .getSource()).allInstances();
0799: RequestProcessor.getDefault().post(new Runnable() {
0800: public void run() {
0801: DeploymentPropertiesHandler
0802: .loadDeploymentProperties(result);
0803: }
0804: }, 200);
0805: }
0806: }
0807:
0808: private void refreshBuildScripts(
0809: final boolean checkForProjectXmlModified) {
0810: RequestProcessor.getDefault().post(new Runnable() {
0811: public void run() {
0812: final FileObject root = Repository
0813: .getDefault()
0814: .getDefaultFileSystem()
0815: .findResource(
0816: "Buildsystem/org.netbeans.modules.kjava.j2meproject"); //NOI18N
0817: final LinkedList<FileObject> files = new LinkedList();
0818: files.addAll(Arrays.asList(root.getChildren()));
0819: ProjectManager.mutex().postWriteRequest(new Runnable() {
0820: public void run() {
0821: try {
0822: ProjectManager.getDefault().saveProject(
0823: J2MEProject.this );
0824: } catch (IOException ioe) {
0825: ErrorManager.getDefault().notify(ioe);
0826: }
0827: URL u = null;
0828: while (!files.isEmpty())
0829: try {
0830: FileObject fo = files.removeFirst();
0831: if (fo.getExt().equals("xml")
0832: && isAuthorized(fo)) { //NOI18N
0833: u = fo.isData() ? fo.getURL()
0834: : new URL("", null, -1, fo
0835: .getPath(),
0836: COMPOSED_STREAM_HANDLER); //NOI18N
0837: genFilesHelper.refreshBuildScript(
0838: FileUtil.getRelativePath(
0839: root, fo), u,
0840: checkForProjectXmlModified);
0841: } else if (fo.isFolder()) {
0842: files.addAll(Arrays.asList(fo
0843: .getChildren()));
0844: }
0845: } catch (IOException ioe) {
0846: ErrorManager.getDefault().notify(ioe);
0847: BufferedReader br = null;
0848: if (u != null)
0849: try {
0850: br = new BufferedReader(
0851: new InputStreamReader(u
0852: .openStream()));
0853: String s;
0854: while ((s = br.readLine()) != null)
0855: ErrorManager
0856: .getDefault()
0857: .log(
0858: ErrorManager.ERROR,
0859: s);
0860: } catch (Exception e) {
0861: } finally {
0862: if (br != null)
0863: try {
0864: br.close();
0865: } catch (IOException e) {
0866: }
0867: }
0868: }
0869: }
0870: });
0871: }
0872: });
0873: }
0874:
0875: /**
0876: * Exports the main JAR as an official build product for use from other scripts.
0877: * The type of the artifact will be {@link AntArtifact#TYPE_JAR}.
0878: */
0879: private final class AntArtifactProviderImpl implements
0880: AntArtifactProvider {
0881:
0882: private AntArtifactProviderImpl() {
0883: // Just to avoid creating accessor class
0884: }
0885:
0886: public AntArtifact[] getBuildArtifacts() {
0887: final ProjectConfiguration cfgs[] = configHelper
0888: .getConfigurations().toArray(
0889: new ProjectConfiguration[0]);
0890: AntArtifact art[] = new AntArtifact[cfgs.length];
0891: for (int i = 0; i < cfgs.length; i++) {
0892: art[i] = new J2MEAntArtifact(
0893: configHelper.getDefaultConfiguration().equals(
0894: cfgs[i]) ? null : cfgs[i]
0895: .getDisplayName());
0896: }
0897: return art;
0898: }
0899:
0900: }
0901:
0902: private class J2MEAntArtifact extends AntArtifact {
0903:
0904: private final String configuration;
0905:
0906: public J2MEAntArtifact(String configuration) {
0907: this .configuration = configuration;//NOI18N
0908: }
0909:
0910: public String getCleanTargetName() {
0911: return "clean"; //NOI18N
0912: }
0913:
0914: public File getScriptLocation() {
0915: return helper
0916: .resolveFile(GeneratedFilesHelper.BUILD_XML_PATH);
0917: }
0918:
0919: public String getTargetName() {
0920: return "jar"; //NOI18N
0921: }
0922:
0923: public String getType() {
0924: return JavaProjectConstants.ARTIFACT_TYPE_JAR;
0925: }
0926:
0927: public Project getProject() {
0928: return J2MEProject.this ;
0929: }
0930:
0931: public String getID() {
0932: return configuration == null ? super .getID() : super
0933: .getID()
0934: + "." + configuration;//NOI18N
0935: }
0936:
0937: public URI[] getArtifactLocations() {
0938: final PropertyEvaluator eval = helper
0939: .getStandardPropertyEvaluator();
0940: String path = "dist/"; //NOI18N
0941: if (configuration != null)
0942: path += configuration + "/"; //NOI18N
0943: final String locationResolved = eval.evaluate(path
0944: + J2MEProjectUtils.evaluateProperty(helper,
0945: "dist.jar", configuration)); //NOI18N
0946: if (locationResolved == null) {
0947: return new URI[0];
0948: }
0949: return new URI[] { getScriptLocation().getParentFile()
0950: .toURI().relativize(
0951: helper.resolveFile(locationResolved)
0952: .toURI()) };
0953: }
0954:
0955: public Properties getProperties() {
0956: final Properties p = new Properties();
0957: p.put(DefaultPropertiesDescriptor.CONFIG_ACTIVE,
0958: configuration == null ? "" : configuration);
0959: return p;
0960: }
0961:
0962: }
0963:
0964: private final class Info implements ProjectInformation {
0965:
0966: private final PropertyChangeSupport pcs = new PropertyChangeSupport(
0967: this );
0968:
0969: Info() {
0970: // Just to avoid creating accessor class
0971: }
0972:
0973: void firePropertyChange(final String prop) {
0974: pcs.firePropertyChange(prop, null, null);
0975: }
0976:
0977: public String getName() {
0978: return PropertyUtils.getUsablePropertyName(J2MEProject.this
0979: .getName());
0980: }
0981:
0982: public String getDisplayName() {
0983: return J2MEProject.this .getName();
0984: }
0985:
0986: public Icon getIcon() {
0987: return J2ME_PROJECT_ICON;
0988: }
0989:
0990: public Project getProject() {
0991: return J2MEProject.this ;
0992: }
0993:
0994: public void addPropertyChangeListener(
0995: final PropertyChangeListener listener) {
0996: pcs.addPropertyChangeListener(listener);
0997: }
0998:
0999: public void removePropertyChangeListener(
1000: final PropertyChangeListener listener) {
1001: pcs.removePropertyChangeListener(listener);
1002: }
1003:
1004: }
1005:
1006: private static final class RecommendedTemplatesImpl implements
1007: RecommendedTemplates, PrivilegedTemplates {
1008:
1009: private static final String LOCATION = "RecommendedTemplates/org.netbeans.modules.kjava.j2meproject"; //NOI18N
1010:
1011: private RecommendedTemplatesImpl() {
1012: }
1013:
1014: public String[] getRecommendedTypes() {
1015: FileObject root = Repository.getDefault()
1016: .getDefaultFileSystem().findResource(LOCATION);
1017: HashSet<String> result = new HashSet();
1018: for (FileObject fo : root.getChildren()) {
1019: String s = (String) fo
1020: .getAttribute("RecommendedTemplates"); //NOI18N
1021: if (s != null)
1022: result.addAll(Arrays.asList(s.split(","))); //NOI18N
1023: }
1024: return result.toArray(new String[result.size()]);
1025: }
1026:
1027: public String[] getPrivilegedTemplates() {
1028: //priviledged templates are ordered by module layer
1029: DataFolder root = DataFolder.findFolder(Repository
1030: .getDefault().getDefaultFileSystem().findResource(
1031: LOCATION));
1032: ArrayList<String> result = new ArrayList();
1033: for (DataObject ch : root.getChildren()) {
1034: String s = (String) ch.getPrimaryFile().getAttribute(
1035: "PriviledgedTemplates"); //NOI18N
1036: if (s != null)
1037: result.addAll(Arrays.asList(s.split(","))); //NOI18N
1038: }
1039: return result.toArray(new String[result.size()]);
1040: }
1041:
1042: }
1043:
1044: private static final class ComposedConnection extends URLConnection {
1045:
1046: private static WeakHashMap<URL, byte[]> cache = new WeakHashMap();
1047:
1048: public ComposedConnection(URL u) {
1049: super (u);
1050: }
1051:
1052: public synchronized InputStream getInputStream()
1053: throws IOException {
1054: boolean log = Boolean
1055: .getBoolean("mobility.report.composed.stylesheets");//NOI18N
1056: byte[] data = cache.get(getURL());
1057: if (data == null) {
1058: DataFolder root = DataFolder.findFolder(Repository
1059: .getDefault().getDefaultFileSystem()
1060: .findResource(getURL().getPath()));
1061: DataObject mainParts[] = root.getChildren();
1062: StringBuffer sb = new StringBuffer();
1063: String lastTarget = ""; //NOI18N
1064: for (int i = 0; i < mainParts.length; i++) {
1065: if (mainParts[i] instanceof DataFolder) {
1066: DataObject subParts[] = ((DataFolder) mainParts[i])
1067: .getChildren();
1068: StringBuffer subTargets = new StringBuffer(
1069: lastTarget);
1070: for (int j = 0; j < subParts.length; j++) {
1071: FileObject fo = subParts[j]
1072: .getPrimaryFile();
1073: if (fo.isData() && isAuthorized(fo)) {
1074: String s = read(subParts[j]
1075: .getPrimaryFile(), lastTarget);
1076: sb.append(s);
1077: subTargets.append(',').append(
1078: subParts[j].getName());
1079: if (log)
1080: ErrorManager.getDefault().log(
1081: ErrorManager.WARNING,
1082: fo.getURL()
1083: .toExternalForm()
1084: + '\n' + s + '\n');
1085: }
1086: }
1087: lastTarget = subTargets.toString();
1088: } else {
1089: FileObject fo = mainParts[i].getPrimaryFile();
1090: if (isAuthorized(fo)) {
1091: String s = read(fo, lastTarget);
1092: sb.append(s);
1093: lastTarget = mainParts[i].getName();
1094: if (log)
1095: ErrorManager.getDefault().log(
1096: ErrorManager.WARNING,
1097: fo.getURL().toExternalForm()
1098: + '\n' + s + '\n');
1099: }
1100: }
1101: }
1102: data = sb.toString().getBytes("UTF-8"); //NOI18N
1103: synchronized (cache) {
1104: cache.put(getURL(), data);
1105: }
1106: if (log)
1107: ErrorManager.getDefault().log(
1108: ErrorManager.WARNING,
1109: getURL().toExternalForm() + '\n'
1110: + sb.toString() + '\n');
1111: }
1112: return new ByteArrayInputStream(data);
1113: }
1114:
1115: public void connect() throws IOException {
1116: }
1117:
1118: private String read(FileObject fo, String dependencies)
1119: throws IOException {
1120: int i = (int) fo.getSize();
1121: byte buff[] = new byte[i];
1122: DataInputStream in = new DataInputStream(fo
1123: .getInputStream());
1124: try {
1125: in.readFully(buff);
1126: assert in.read() == -1;
1127: } finally {
1128: in.close();
1129: }
1130: return new String(buff, "UTF-8").replace("__DEPENDS__",
1131: dependencies); //NOI18N
1132: }
1133:
1134: }
1135:
1136: // private static final Set<File> FRIENDS_JARS = collectFriendJars();
1137: //
1138: // private static Set<String> getFriends() {
1139: // Iterator<? extends ModuleInfo> it = Lookup.getDefault().lookupResult(ModuleInfo.class).allInstances().iterator();
1140: // while (it.hasNext()) {
1141: // ModuleInfo mi = it.next();
1142: // if ("org.netbeans.modules.mobility.project".equals(mi.getCodeNameBase())) { //NOI18N
1143: // HashSet<String> friends = new HashSet<String>(Arrays.asList(((String)mi.getAttribute("OpenIDE-Module-Friends")).split("[,\\s]+"))); //NOI18N
1144: // friends.add("org.netbeans.modules.mobility.project"); //NOI18N
1145: // return friends;
1146: // }
1147: // }
1148: // return null;
1149: // }
1150: //
1151: // private static Set<File> collectFriendJars() {
1152: // Set<String> friends = getFriends();
1153: // if (friends == null) return null;
1154: // Set<File> jars = new HashSet<File>();
1155: // Iterator<? extends ModuleInfo> it = Lookup.getDefault().lookupResult(ModuleInfo.class).allInstances().iterator();
1156: // while (it.hasNext()) {
1157: // ModuleInfo mi = it.next();
1158: // if (friends.contains(mi.getCodeNameBase())) try {
1159: // Field f = mi.getClass().getDeclaredField("jar");//NOI18N
1160: // f.setAccessible(true);
1161: // File ff = (File)f.get(mi); //gettings field jar from StandardModule
1162: // if (ff != null) jars.add(ff);
1163: // } catch (Exception e) {};
1164: // }
1165: // if (jars.size() == 0) {
1166: // ErrorManager.getDefault().log(ErrorManager.WARNING, "Mobility Project Buildsystem cannot collect list of friend JARs."); //NOI18N
1167: // return null;
1168: // }
1169: // return jars;
1170: // }
1171:
1172: private static boolean isAuthorized(FileObject fo) {
1173: // if (fo.isFolder() || FRIENDS_JARS == null) return true;
1174: // URL u = null;
1175: // try {
1176: // u = fo.getURL();
1177: // //looking for MultiFileObject.leader field
1178: // Field f = fo.getClass().getDeclaredField("leader"); //NOI18N
1179: // f.setAccessible(true);
1180: // fo = (FileObject)f.get(fo); //getting the leader FileObject...
1181: // fo = (FileObject)f.get(fo); //...twice
1182: // File ff = FileUtil.toFile(fo);
1183: // if (ff == null) { //FileObject does not represent physical file
1184: // f = fo.getClass().getDeclaredField("uri"); //looking for BFSFile.uri field //NOI18N
1185: // f.setAccessible(true);
1186: // String s = (String)f.get(fo);
1187: // if (s == null) return true; //the uri field is not declared - empty file
1188: // u = new URL(s);
1189: // //URL points to module jar content, no other protocols are allowed and the jar must be listed as friend
1190: // if ("jar".equals(u.getProtocol()) && FRIENDS_JARS.contains(new File(FileUtil.getArchiveFile(u).toURI()))) return true; //NOI18N
1191: // } else { //FileObject represents physical file (userdir or installdir / config /...) - this is not allowed
1192: // u = ff.toURL();
1193: // }
1194: // ErrorManager.getDefault().log(ErrorManager.WARNING, "Unauthorized access to Mobility Project Build System from: " + String.valueOf(u)); //NOI18N
1195: // return false;
1196: // } catch (Exception e) {
1197: // ErrorManager.getDefault().log(ErrorManager.WARNING, "Cannot verify access authorization to Mobility Project Build System from: " + String.valueOf(u)); //NOI18N
1198: // ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e);
1199: // return true;
1200: // }
1201: return true;
1202: }
1203:
1204: private static String normalizePath(File path, File jdkHome,
1205: String propName) {
1206: String jdkLoc = jdkHome.getAbsolutePath();
1207: if (!jdkLoc.endsWith(File.separator)) {
1208: jdkLoc = jdkLoc + File.separator;
1209: }
1210: String loc = path.getAbsolutePath();
1211: if (loc.startsWith(jdkLoc)) {
1212: return "${" + propName + "}" + File.separator
1213: + loc.substring(jdkLoc.length()); //NOI18N
1214: }
1215: return loc;
1216: }
1217:
1218: private List<ProjectConfiguration> getMatchingConfigs(
1219: final String actualPlatformId) {
1220: List<ProjectConfiguration> configs = new ArrayList<ProjectConfiguration>();
1221:
1222: for (ProjectConfiguration config : getConfigurationHelper()
1223: .getConfigurations()) {
1224: boolean useDef = config.equals(getConfigurationHelper()
1225: .getDefaultConfiguration());
1226: String platformProp = VisualPropertySupport
1227: .translatePropertyName(
1228: config.getDisplayName(),
1229: DefaultPropertiesDescriptor.PLATFORM_ACTIVE,
1230: useDef);
1231: String platformId = helper.getProperties(
1232: AntProjectHelper.PROJECT_PROPERTIES_PATH)
1233: .getProperty(platformProp);
1234:
1235: //platformId is null when non default config, which use default values, is queried
1236: //This one is not important for us as the change will be/have been done using DefaultConfiguration
1237: if (platformId != null
1238: && platformId.equals(actualPlatformId)) {
1239: configs.add(config);
1240: }
1241: }
1242: return configs;
1243: }
1244:
1245: private void generatePlatformProperties(CDCPlatform platform,
1246: ProjectConfiguration config, String activeDevice,
1247: String activeProfile, EditableProperties props) {
1248: Collection<FileObject> installFolders = platform
1249: .getInstallFolders();
1250: if (installFolders.size() > 0) {
1251: File jdkHome = FileUtil.toFile(installFolders.iterator()
1252: .next());
1253: StringBuffer sbootcp = new StringBuffer();
1254: ClassPath bootCP = platform
1255: .getBootstrapLibrariesForProfile(activeDevice,
1256: activeProfile);
1257: for (ClassPath.Entry entry : (List<ClassPath.Entry>) bootCP
1258: .entries()) {
1259: URL url = entry.getURL();
1260: if ("jar".equals(url.getProtocol())) { //NOI18N
1261: url = FileUtil.getArchiveFile(url);
1262: }
1263: File root = new File(URI.create(url.toExternalForm()));
1264: if (sbootcp.length() > 0) {
1265: sbootcp.append(File.pathSeparator);
1266: }
1267: sbootcp.append(normalizePath(root, jdkHome,
1268: "platform.home"));
1269: }
1270: boolean useDef = config.equals(getConfigurationHelper()
1271: .getDefaultConfiguration());
1272: props
1273: .setProperty(
1274: VisualPropertySupport
1275: .translatePropertyName(
1276: config.getDisplayName(),
1277: DefaultPropertiesDescriptor.PLATFORM_BOOTCLASSPATH,
1278: useDef), sbootcp.toString()); //NOI18N
1279: }
1280: }
1281:
1282: private void updateBootClassPathProperty(
1283: List<ProjectConfiguration> configs, CDCPlatform platform) {
1284: if (configs != null) {
1285: try {
1286: EditableProperties props = helper
1287: .getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH);
1288: for (ProjectConfiguration config : configs) {
1289: boolean useDef = config
1290: .equals(getConfigurationHelper()
1291: .getDefaultConfiguration());
1292: generatePlatformProperties(
1293: platform,
1294: config,
1295: props
1296: .getProperty(VisualPropertySupport
1297: .translatePropertyName(
1298: config
1299: .getDisplayName(),
1300: DefaultPropertiesDescriptor.PLATFORM_DEVICE,
1301: useDef)),
1302: props
1303: .getProperty(VisualPropertySupport
1304: .translatePropertyName(
1305: config
1306: .getDisplayName(),
1307: DefaultPropertiesDescriptor.PLATFORM_PROFILE,
1308: useDef)), props);
1309: }
1310: helper
1311: .putProperties(
1312: AntProjectHelper.PROJECT_PROPERTIES_PATH,
1313: props);
1314: ProjectManager.getDefault().saveProject(this );
1315: } catch (IOException ex) {
1316: ErrorManager.getDefault().notify(ex);
1317: }
1318: }
1319: }
1320: }
|