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 org.netbeans.api.java.platform.JavaPlatform;
0045: import org.netbeans.api.java.platform.JavaPlatformManager;
0046: import org.netbeans.api.java.platform.Profile;
0047: import org.netbeans.api.java.platform.Specification;
0048: import org.netbeans.api.mobility.project.PropertyDescriptor;
0049: import org.netbeans.api.project.Project;
0050: import org.netbeans.api.project.ProjectManager;
0051: import org.netbeans.spi.project.ProjectConfiguration;
0052: import org.netbeans.api.queries.CollocationQuery;
0053: import org.netbeans.modules.mobility.cldcplatform.J2MEPlatform;
0054: import org.netbeans.modules.mobility.cldcplatform.PlatformConvertor;
0055: import org.netbeans.modules.mobility.project.ui.customizer.J2MEProjectProperties;
0056: import org.netbeans.modules.mobility.project.ui.wizard.PlatformSelectionPanel;
0057: import org.netbeans.modules.mobility.project.ui.wizard.Utils;
0058: import org.netbeans.modules.mobility.project.deployment.CopyDeploymentPlugin;
0059: import org.netbeans.spi.mobility.project.ProjectPropertiesDescriptor;
0060: import org.netbeans.spi.mobility.project.support.DefaultPropertyParsers;
0061: import org.netbeans.spi.project.support.ant.AntProjectHelper;
0062: import org.netbeans.spi.project.support.ant.EditableProperties;
0063: import org.netbeans.spi.project.support.ant.ProjectGenerator;
0064: import org.netbeans.spi.project.support.ant.PropertyUtils;
0065: import org.netbeans.spi.project.ui.support.ProjectChooser;
0066: import org.openide.DialogDisplayer;
0067: import org.openide.NotifyDescriptor;
0068: import org.openide.filesystems.FileObject;
0069: import org.openide.filesystems.FileSystem;
0070: import org.openide.filesystems.FileUtil;
0071: import org.openide.filesystems.Repository;
0072: import org.openide.loaders.DataFolder;
0073: import org.openide.loaders.DataObject;
0074: import org.openide.loaders.DataObjectNotFoundException;
0075: import org.openide.modules.SpecificationVersion;
0076: import org.openide.util.Lookup;
0077: import org.openide.xml.XMLUtil;
0078: import org.w3c.dom.DOMException;
0079: import org.w3c.dom.Document;
0080: import org.w3c.dom.Element;
0081: import org.w3c.dom.Node;
0082: import org.xml.sax.ErrorHandler;
0083: import org.xml.sax.InputSource;
0084: import org.xml.sax.SAXException;
0085: import org.xml.sax.SAXParseException;
0086: import java.io.*;
0087: import java.text.MessageFormat;
0088: import java.util.*;
0089: import java.util.zip.ZipEntry;
0090: import java.util.zip.ZipInputStream;
0091: import java.util.jar.Manifest;
0092: import java.util.jar.Attributes;
0093: import java.util.regex.Pattern;
0094: import java.beans.PropertyVetoException;
0095: import javax.swing.DefaultComboBoxModel;
0096: import javax.swing.event.ChangeEvent;
0097: import javax.swing.event.ChangeListener;
0098: import org.netbeans.api.queries.FileEncodingQuery;
0099: import org.netbeans.spi.mobility.project.ui.customizer.support.VisualPropertySupport;
0100: import org.openide.util.NbBundle;
0101: import org.netbeans.modules.mobility.project.ui.customizer.MIDletScanner;
0102: import org.netbeans.spi.mobility.cfgfactory.ProjectConfigurationFactory.ConfigurationTemplateDescriptor;
0103: import org.netbeans.spi.project.support.ant.ReferenceHelper;
0104:
0105: /**
0106: * Create a fresh J2MEProject from scratch.
0107: * Currently does not permit much to be specified - feel free to add more parameters
0108: * as needed.
0109: * @author Jesse Glick, Adam Sotona, David Kaspar
0110: */
0111: public class J2MEProjectGenerator {
0112:
0113: public static final Pattern IMPORT_EXCLUDES = Pattern
0114: .compile("^(.*/)?(([^/]*~)|(#[^/]*#)|(\\.#[^/]*)|(%[^/]*%)|(\\._[^/]*)|(CVS)|(CVS/.*)|(\\.cvsignore)|(SCCS)|(SCCS/.*)|(vssver\\.scc)|(\\.svn)|(\\.svn/.*)|(\\.DS_Store)|([^/]*\\.class)|([^/]*\\.adContent)|([^/]*\\.jad)|([^/]*\\.nbattrs))$");//NOI18N
0115: public static final Pattern IMPORT_SRC_EXCLUDES = Pattern
0116: .compile("^(.*/)?(([^/]*~)|(#[^/]*#)|(\\.#[^/]*)|(%[^/]*%)|(\\._[^/]*)|(CVS)|(CVS/.*)|(\\.cvsignore)|(SCCS)|(SCCS/.*)|(vssver\\.scc)|(\\.svn)|(\\.svn/.*)|(\\.DS_Store)|([^/]*\\.class)|([^/]*\\.adContent)|([^/]*\\.jad)|([^/]*\\.jar)|([^/]*\\.zip)|([^/]*\\.nbattrs))$");//NOI18N
0117: public static final String DEFAULT_ENCODING = "UTF-8"; // NO I18N
0118: public static final String TRUE = "true"; //NOI18N
0119: public static final String FALSE = "false"; //NOI18N
0120: public static final String EMPTY = ""; //NOI18N
0121: private static final HashSet<String> KNOWN_ATTRIBUTES = new HashSet<String>(
0122: Arrays.asList(new String[] { "MIDlet-Name",
0123: "MIDlet-Vendor",
0124: "MIDlet-Version",
0125: "MIDlet-Icon",
0126: "MIDlet-Description",
0127: "MIDlet-Info-URL", //NOI18N
0128: "MIDlet-Data-Size", //NOI18N
0129: "MIDlet-Install-Notify",
0130: "MIDlet-Delete-Notify",
0131: "MIDlet-Delete-Confirm", //NOI18N
0132: "MicroEdition-Configuration",
0133: "MicroEdition-Profile", //NOI18N
0134: }));
0135: private static final String PRIVATE_PREFIX = "private."; //NOI18N
0136: private static final String SRC = "src";
0137: private static final String NAME = "name";
0138: private static final String MIDLET = "MIDlet-";
0139:
0140: private J2MEProjectGenerator() {
0141: //Just to avoid accessor class creation
0142: }
0143:
0144: public static AntProjectHelper createProjectFromSources(
0145: final File projectLocation, final String name,
0146: final PlatformSelectionPanel.PlatformDescription platform,
0147: final String sourcesLocation, final String jadLocation)
0148: throws IOException {
0149: return createProject(projectLocation, name, platform,
0150: new ProjectGeneratorCallback() {
0151: public void doPostGeneration(Project project,
0152: AntProjectHelper helper,
0153: @SuppressWarnings("unused")
0154: FileObject projectLocation,
0155: @SuppressWarnings("unused")
0156: File projectLocationFile,
0157: @SuppressWarnings("unused")
0158: ArrayList configurations)
0159: throws IOException {
0160: setSourceRoot(helper,
0161: getReferenceHelper(project),
0162: sourcesLocation);
0163: loadJadManifest(helper, new File(jadLocation));
0164: fillMissingMIDlets(project, helper);
0165: }
0166: });
0167: }
0168:
0169: public static AntProjectHelper createProjectFromSuite(
0170: final File projectLocation, final String name,
0171: final PlatformSelectionPanel.PlatformDescription platform,
0172: final String suite, final String sources)
0173: throws IOException {
0174: return createProject(projectLocation, name, platform,
0175: new ProjectGeneratorCallback() {
0176: public void doPostGeneration(Project project,
0177: AntProjectHelper helper,
0178: @SuppressWarnings("unused")
0179: FileObject projectLocation,
0180: @SuppressWarnings("unused")
0181: File projectLocationFile,
0182: @SuppressWarnings("unused")
0183: ArrayList configurations)
0184: throws IOException {
0185: setSourceRoot(helper,
0186: getReferenceHelper(project), sources);
0187: loadSettingFromSuite(helper, new File(suite));
0188: fillMissingMIDlets(project, helper);
0189: }
0190: });
0191: }
0192:
0193: public static void copyFolder(File source, File target,
0194: Pattern filter) throws IOException {
0195: if (isParent(source, target))
0196: return;
0197: File[] files = source.listFiles();
0198: if (files != null)
0199: for (int a = 0; a < files.length; a++) {
0200: File file = files[a];
0201: if (filter.matcher(
0202: file.getAbsolutePath().replace('\\', '/'))
0203: .matches())
0204: continue;
0205: if (file.isDirectory()) {
0206: File subdir = new File(target, file.getName());
0207: subdir.mkdirs();
0208: copyFolder(file, subdir, filter);
0209: } else {
0210: FileInputStream fis = null;
0211: FileOutputStream fos = null;
0212: try {
0213: fis = new FileInputStream(file);
0214: fos = new FileOutputStream(new File(target,
0215: file.getName()));
0216: FileUtil.copy(fis, fos);
0217: } finally {
0218: if (fis != null)
0219: try {
0220: fis.close();
0221: } catch (IOException e) {
0222: }
0223: if (fos != null)
0224: try {
0225: fos.close();
0226: } catch (IOException e) {
0227: }
0228: }
0229: }
0230: }
0231: }
0232:
0233: public static AntProjectHelper createProjectFromWtkProject(
0234: final File projectLocation, final String name,
0235: final PlatformSelectionPanel.PlatformDescription platform,
0236: final String appLocation) throws IOException {
0237: return createProject(projectLocation, name, platform,
0238: new ProjectGeneratorCallback() {
0239: public void doPostGeneration(Project project,
0240: AntProjectHelper helper,
0241: @SuppressWarnings("unused")
0242: FileObject projectLocation,
0243: File projectLocationFile,
0244: @SuppressWarnings("unused")
0245: ArrayList configurations)
0246: throws IOException {
0247: final ReferenceHelper refHelper = getReferenceHelper(project);
0248:
0249: FileObject src = projectLocation
0250: .createFolder("src"); //NOI18N
0251: File srcFile = FileUtil.toFile(src);
0252: FileObject lib = projectLocation
0253: .createFolder("lib"); //NOI18N
0254: File libFile = FileUtil.toFile(lib);
0255: FileObject res = projectLocation
0256: .createFolder("res"); //NOI18N
0257: File resFile = FileUtil.toFile(res);
0258: copyJavaFolder(new File(appLocation, "src"),
0259: srcFile, IMPORT_SRC_EXCLUDES); //NOI18N
0260: copyFolder(new File(appLocation, "res"),
0261: resFile, IMPORT_SRC_EXCLUDES); //NOI18N
0262: copyFolder(new File(appLocation, "lib"),
0263: libFile, IMPORT_EXCLUDES); //NOI18N
0264:
0265: //setSourceRoot(helper, refHelper, new File(appLocation, SRC).getAbsolutePath()); //NOI18N
0266: final File jad = findWtkJadFile(appLocation);
0267: final File mf = findWtkManifestFile(appLocation);
0268: loadJadAndManifest(helper, jad, mf);
0269: loadWTKProperties(helper, projectLocationFile);
0270:
0271: final File[] files = libFile.listFiles(); //NOI18N
0272: File[] libs = null;
0273: if (files == null) {
0274: libs = new File[1];
0275: } else {
0276: libs = new File[files.length + 1];
0277: System.arraycopy(files, 0, libs, 1,
0278: files.length);
0279: }
0280: libs[0] = resFile; //NOI18N
0281: loadLibraries(helper, refHelper, libs);
0282: fillMissingMIDlets(project, helper);
0283: }
0284: });
0285: }
0286:
0287: public static AntProjectHelper duplicateProject(
0288: final J2MEProject oldProject, final File _projectLocation,
0289: final String name, final boolean copySources)
0290: throws IOException {
0291: final FileObject projectLocation = createProjectLocation(_projectLocation);
0292: final AntProjectHelper h = ProjectGenerator.createProject(
0293: projectLocation, J2MEProjectType.TYPE);
0294: final AntProjectHelper oldHelper = oldProject.getLookup()
0295: .lookup(AntProjectHelper.class);
0296: final Element data = h.getPrimaryConfigurationData(true);
0297: final Document doc = data.getOwnerDocument();
0298: final Element nameEl = doc.createElementNS(
0299: J2MEProjectType.PROJECT_CONFIGURATION_NAMESPACE, NAME); // NOI18N
0300: nameEl.appendChild(doc.createTextNode(name));
0301: data.appendChild(nameEl);
0302: final Element minant = doc.createElementNS(
0303: J2MEProjectType.PROJECT_CONFIGURATION_NAMESPACE,
0304: "minimum-ant-version"); // NOI18N
0305: minant.appendChild(doc.createTextNode("1.6")); // NOI18N
0306: data.appendChild(minant);
0307: h.putPrimaryConfigurationData(data, true);
0308: final EditableProperties ep = oldHelper.getProperties(
0309: AntProjectHelper.PROJECT_PROPERTIES_PATH)
0310: .cloneProperties();
0311: final EditableProperties ep2 = oldHelper.getProperties(
0312: AntProjectHelper.PRIVATE_PROPERTIES_PATH)
0313: .cloneProperties();
0314: ep.setProperty(DefaultPropertiesDescriptor.SRC_DIR, SRC); //NOI18N
0315: ep.setProperty(NAME, name); //NOI18N
0316: final File projDir = FileUtil.toFile(projectLocation);
0317: assert projDir != null : "FileUtil.toFile convertion failed for: "
0318: + projectLocation; //NOI18N
0319: for (final String key : (Set<String>) ep.keySet()) {
0320: if (key.startsWith("file.reference.")
0321: || key.startsWith("project.")) {//NOI18N
0322: final String pValue = ep.getProperty(key);
0323: if (pValue.indexOf("${") < 0) { //NOI18N
0324: final File f = oldHelper.resolveFile(pValue);
0325: String newPath;
0326: if (CollocationQuery.areCollocated(projDir, f)
0327: && (newPath = PropertyUtils.relativizeFile(
0328: projDir, f)) != null) {
0329: // Fine, using a relative path to subproject and store it back.
0330: ep.put(key, newPath);
0331: } else {
0332: // Use an absolute path, remove the reference form project.properties and store it into private.properties.
0333: ep.remove(key);
0334: ep2.put(key, f.getAbsolutePath());
0335: }
0336: }
0337: }
0338: }
0339: h.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH, ep);
0340: h.putProperties(AntProjectHelper.PRIVATE_PROPERTIES_PATH, ep2);
0341: final Project prj = ProjectManager.getDefault().findProject(
0342: projectLocation);
0343: final ProjectConfigurationsHelper oldCfgHlp = oldProject
0344: .getLookup().lookup(ProjectConfigurationsHelper.class);
0345: final ProjectConfiguration cfgs[] = oldCfgHlp
0346: .getConfigurations().toArray(
0347: new ProjectConfiguration[0]);
0348: final ProjectConfigurationsHelper cfgHlp = prj.getLookup()
0349: .lookup(ProjectConfigurationsHelper.class);
0350: for (int a = 0; a < cfgs.length; a++) {
0351: if (!oldCfgHlp.getDefaultConfiguration().equals(cfgs[a]))
0352: cfgHlp.addConfiguration(cfgs[a].getDisplayName());
0353: }
0354: final ReferenceHelper oldRefHelper = oldProject.getLookup()
0355: .lookup(ReferenceHelper.class);
0356: final ReferenceHelper refHelper = prj.getLookup().lookup(
0357: ReferenceHelper.class);
0358: final ReferenceHelper.RawReference rawRef[] = oldRefHelper
0359: .getRawReferences();
0360: if (rawRef != null)
0361: for (int i = 0; i < rawRef.length; i++) {
0362: refHelper.addRawReference(rawRef[i]);
0363: }
0364: if (prj instanceof J2MEProject)
0365: ((J2MEProject) prj).hookNewProjectCreated();
0366: final FileObject src = projectLocation.createFolder(SRC); // NOI18N
0367: if (copySources)
0368: copyJavaFolder(oldHelper.resolveFile(oldHelper
0369: .getStandardPropertyEvaluator().getProperty(
0370: DefaultPropertiesDescriptor.SRC_DIR)),
0371: FileUtil.toFile(src), IMPORT_SRC_EXCLUDES);
0372: refreshProject(projectLocation, src);
0373: ProjectManager.getDefault().saveProject(prj);
0374: return h;
0375: }
0376:
0377: public static AntProjectHelper createNewProject(
0378: final File projectLocation, final String name,
0379: final PlatformSelectionPanel.PlatformDescription platform,
0380: final Collection<DataObject> createHelloMIDlet,
0381: final Set<ConfigurationTemplateDescriptor> cfgTemplates)
0382: throws IOException {
0383: return createProject(projectLocation, name, platform,
0384: new ProjectGeneratorCallback() {
0385: public void doPostGeneration(Project project,
0386: AntProjectHelper helper,
0387: FileObject projectLocation,
0388: @SuppressWarnings("unused")
0389: File projectLocationFile,
0390: ArrayList<String> configurations)
0391: throws IOException {
0392: final FileObject src = projectLocation
0393: .createFolder(SRC); // NOI18N
0394: if (createHelloMIDlet != null) {
0395: FileObject hello = src
0396: .createFolder("hello"); // NOI18N
0397: if (hello == null)
0398: hello = src;
0399: final DataFolder helloFolder = DataFolder
0400: .findFolder(hello);
0401: final FileSystem dfs = Repository
0402: .getDefault()
0403: .getDefaultFileSystem();
0404: FileObject foTemplate = dfs
0405: .findResource("Templates/MIDP/HelloMIDlet.java"); //NOI18N
0406: if (foTemplate == null)
0407: foTemplate = dfs
0408: .findResource("Templates/MIDP/Midlet.java"); //NOI18N
0409: try {
0410: if (foTemplate != null) {
0411: final DataObject template = DataObject
0412: .find(foTemplate);
0413: if (template != null) {
0414: // Remove ".java" suffix
0415: String name = template
0416: .getName();
0417: if (name.endsWith(".java")) {
0418: name = name.substring(0,
0419: name.length() - 5);
0420: }
0421: DataObject fromTemplate = template
0422: .createFromTemplate(helloFolder);
0423: try {
0424: fromTemplate
0425: .setValid(false);
0426: } catch (PropertyVetoException e) {
0427: e.printStackTrace(); // TODO
0428: }
0429: fromTemplate = DataObject
0430: .find(fromTemplate
0431: .getPrimaryFile());
0432: createHelloMIDlet
0433: .add(fromTemplate);
0434: addMIDletProperty(project,
0435: helper, name,
0436: hello != src ? "hello."
0437: + name : name,
0438: ""); // NOI18N
0439: }
0440: }
0441: } catch (DataObjectNotFoundException e) {
0442: e.printStackTrace();
0443: }
0444: }
0445: if (cfgTemplates != null) {
0446: final EditableProperties priv = helper
0447: .getProperties(AntProjectHelper.PRIVATE_PROPERTIES_PATH);
0448: final EditableProperties proj = helper
0449: .getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH);
0450: for (ConfigurationTemplateDescriptor desc : cfgTemplates) {
0451: String cfgName = desc.getCfgName();
0452: String prefix = J2MEProjectProperties.CONFIG_PREFIX
0453: + cfgName + '.';
0454: if (!configurations.contains(cfgName)) {
0455: configurations.add(cfgName);
0456: Map<String, String> p = desc
0457: .getPrivateProperties();
0458: if (p != null)
0459: for (Map.Entry<String, String> en : p
0460: .entrySet()) {
0461: if (!priv.containsKey(en
0462: .getKey()))
0463: priv.put(en.getKey(),
0464: en.getValue());
0465: }
0466: p = desc
0467: .getProjectGlobalProperties();
0468: if (p != null)
0469: for (Map.Entry<String, String> en : p
0470: .entrySet()) {
0471: if (!proj.containsKey(en
0472: .getKey()))
0473: proj.put(en.getKey(),
0474: en.getValue());
0475: }
0476: p = desc
0477: .getProjectConfigurationProperties();
0478: if (p != null)
0479: for (Map.Entry<String, String> en : p
0480: .entrySet()) {
0481: proj.put(prefix
0482: + en.getKey(), en
0483: .getValue());
0484: }
0485: }
0486: }
0487: helper
0488: .putProperties(
0489: AntProjectHelper.PRIVATE_PROPERTIES_PATH,
0490: priv);
0491: helper
0492: .putProperties(
0493: AntProjectHelper.PROJECT_PROPERTIES_PATH,
0494: proj);
0495: }
0496: refreshProject(projectLocation, src);
0497: }
0498: });
0499: }
0500:
0501: public static AntProjectHelper createProjectFromTemplate(
0502: final FileObject template, final File projectLocation,
0503: final String name,
0504: final PlatformSelectionPanel.PlatformDescription platform)
0505: throws IOException {
0506: return createProject(projectLocation, name, platform,
0507: new ProjectGeneratorCallback() {
0508: public void doPostGeneration(
0509: @SuppressWarnings("unused")
0510: Project project, AntProjectHelper helper,
0511: FileObject projectLocation,
0512: File projectLocationFile,
0513: ArrayList<String> configurations)
0514: throws IOException {
0515: FileObject src = null;
0516: if (template.getExt().endsWith("zip")) { //NOI18N
0517: unzip(template.getInputStream(),
0518: projectLocationFile);
0519: final File jadFile = Utils.findAnyFile(
0520: projectLocationFile.listFiles(),
0521: "jad"); // NOI18N
0522: if (jadFile != null) {
0523: loadJadManifest(helper, jadFile);
0524: jadFile.delete();
0525: }
0526: final File metaInfDir = new File(
0527: projectLocationFile, "META-INF"); //NOI18N
0528: final File projectPropertiesFile = new File(
0529: metaInfDir, "project.properties"); //NOI18N
0530: if (projectPropertiesFile.exists()
0531: && projectPropertiesFile.canRead()) {
0532: final Properties props = new Properties();
0533: FileInputStream fis = null;
0534: try {
0535: fis = new FileInputStream(
0536: projectPropertiesFile);
0537: props.load(fis);
0538: final Enumeration e = props.keys();
0539: while (e.hasMoreElements()) {
0540: String name = (String) e
0541: .nextElement();
0542: if (!name
0543: .startsWith(J2MEProjectProperties.CONFIG_PREFIX))
0544: continue;
0545: name = name
0546: .substring(J2MEProjectProperties.CONFIG_PREFIX
0547: .length());
0548: final int i = name.indexOf('.'); //NOI18N
0549: if (i >= 0)
0550: name = name.substring(0, i);
0551: if (!configurations
0552: .contains(name))
0553: configurations.add(name);
0554: }
0555: setProperties(helper, props);
0556: } finally {
0557: if (fis != null)
0558: try {
0559: fis.close();
0560: } catch (IOException e) {
0561: }
0562: }
0563: deleteAll(metaInfDir);
0564: }
0565: projectLocation.refresh(false);
0566: } else {
0567: src = projectLocation.createFolder(SRC); // NOI18N
0568: }
0569: refreshProject(projectLocation, src);
0570: }
0571: });
0572: }
0573:
0574: public static interface ProjectGeneratorCallback {
0575:
0576: public void doPostGeneration(Project project,
0577: AntProjectHelper helper, FileObject projectLocation,
0578: File projectLocationFile,
0579: ArrayList<String> configurations) throws IOException;
0580:
0581: }
0582:
0583: /**
0584: * Create a new empty J2ME project.
0585: * @param _projectLocation the top-level directory (need not yet exist but if it does it must be empty)
0586: * @param name the code name for the project
0587: * @param callback project generation callback
0588: * @return the helper object permitting it to be further customized
0589: * @throws IOException in case something went wrong
0590: */
0591: public static AntProjectHelper createProject(
0592: final File _projectLocation, final String name,
0593: final PlatformSelectionPanel.PlatformDescription platform,
0594: final ProjectGeneratorCallback callback) throws IOException {
0595: final FileObject projectLocation = createProjectLocation(_projectLocation);
0596: final AntProjectHelper h = ProjectGenerator.createProject(
0597: projectLocation, J2MEProjectType.TYPE);
0598: final Element data = h.getPrimaryConfigurationData(true);
0599: final Document doc = data.getOwnerDocument();
0600: final Element nameEl = doc.createElementNS(
0601: J2MEProjectType.PROJECT_CONFIGURATION_NAMESPACE, NAME); // NOI18N
0602: nameEl.appendChild(doc.createTextNode(name));
0603: data.appendChild(nameEl);
0604: final Element minant = doc.createElementNS(
0605: J2MEProjectType.PROJECT_CONFIGURATION_NAMESPACE,
0606: "minimum-ant-version"); // NOI18N
0607: minant.appendChild(doc.createTextNode("1.6")); // NOI18N
0608: data.appendChild(minant);
0609: h.putPrimaryConfigurationData(data, true);
0610: EditableProperties ep = h
0611: .getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH);
0612: EditableProperties priv = h
0613: .getProperties(AntProjectHelper.PRIVATE_PROPERTIES_PATH);
0614:
0615: for (ProjectPropertiesDescriptor p : Lookup
0616: .getDefault()
0617: .lookup(
0618: new Lookup.Template<ProjectPropertiesDescriptor>(
0619: ProjectPropertiesDescriptor.class))
0620: .allInstances()) {
0621: for (PropertyDescriptor d : p.getPropertyDescriptors()) {
0622: if (d.getDefaultValue() != null) {
0623: (d.isShared() ? ep : priv).setProperty(d.getName(),
0624: d.getDefaultValue());
0625: }
0626: }
0627: }
0628:
0629: ep.setProperty(DefaultPropertiesDescriptor.BUILD_ROOT_DIR,
0630: "build"); //NOI18N
0631: ep.setProperty(DefaultPropertiesDescriptor.DIST_ROOT_DIR,
0632: "dist"); //NOI18N
0633: ep.setProperty(NAME, name); //NOI18N
0634: ep.setProperty("preprocessed.dir", "${build.dir}/preprocessed"); //NOI18N
0635: ep.setProperty("build.classes.dir", "${build.dir}/compiled"); //NOI18N
0636: ep.setProperty("obfuscator.srcjar",
0637: "${build.dir}/before-obfuscation.jar"); //NOI18N
0638: ep.setProperty("obfuscator.destjar",
0639: "${build.dir}/obfuscated.jar"); //NOI18N
0640: ep.setProperty("obfuscated.classes.dir",
0641: "${build.dir}/obfuscated"); //NOI18N
0642: ep.setProperty("preverify.sources.dir",
0643: "${build.dir}/preverifysrc"); //NOI18N
0644: ep.setProperty("preverify.classes.dir",
0645: "${build.dir}/preverified"); //NOI18N
0646: final String usablePropertyName = PropertyUtils
0647: .getUsablePropertyName(name);
0648: ep.setProperty(DefaultPropertiesDescriptor.DIST_JAR,
0649: usablePropertyName + ".jar"); //NOI18N
0650: ep.setProperty(DefaultPropertiesDescriptor.DIST_JAD,
0651: usablePropertyName + ".jad"); //NOI18N
0652: ep.setProperty("dist.javadoc.dir", "${dist.dir}/doc"); //NOI18N
0653: ep.setProperty(CopyDeploymentPlugin.PROP_TARGET, "deploy"); //NOI18N
0654: ep.setProperty(DefaultPropertiesDescriptor.JAVAC_ENCODING,
0655: FileEncodingQuery.getDefaultEncoding().name());
0656:
0657: final HashMap<String, String> manifestOthers = new HashMap<String, String>();
0658: manifestOthers.put("MIDlet-Name", name); //NOI18N
0659: manifestOthers.put("MIDlet-Vendor", "Vendor"); //NOI18N
0660: manifestOthers.put("MIDlet-Version", "1.0"); //NOI18N
0661: storeManifestProperties(ep,
0662: DefaultPropertiesDescriptor.MANIFEST_OTHERS,
0663: manifestOthers);
0664:
0665: if (platform != null) {
0666: ep.putAll(PlatformConvertor.extractPlatformProperties("",
0667: platform.platform, platform.device,
0668: platform.configuration, platform.profile)); //NOI18N
0669: } else {
0670: ep.putAll(PlatformConvertor.extractPlatformProperties("",
0671: findPlatform(null), null, null, null)); //NOI18N
0672: }
0673:
0674: priv.setProperty("netbeans.user", System
0675: .getProperty("netbeans.user")); //NOI18N
0676: h.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH, ep);
0677: h.putProperties(AntProjectHelper.PRIVATE_PROPERTIES_PATH, priv);
0678: final File projectLocationFile = FileUtil
0679: .toFile(projectLocation);
0680: assert projectLocationFile != null : "FileUtil.toFile convertion failed for: "
0681: + projectLocation; //NOI18N
0682: final ArrayList<String> configurations = new ArrayList<String>();
0683: final Project prj = ProjectManager.getDefault().findProject(
0684: projectLocation);
0685: if (callback != null)
0686: callback.doPostGeneration(prj, h, projectLocation,
0687: projectLocationFile, configurations);
0688: if (!configurations.isEmpty()) {
0689: final ProjectConfigurationsHelper confs = prj.getLookup()
0690: .lookup(ProjectConfigurationsHelper.class);
0691: if (confs != null) {
0692: for (int a = 0; a < configurations.size(); a++) {
0693: final String conf = configurations.get(a);
0694: confs.addConfiguration(conf);
0695: }
0696: }
0697: }
0698: if (prj instanceof J2MEProject)
0699: ((J2MEProject) prj).hookNewProjectCreated();
0700: ProjectManager.getDefault().saveProject(prj);
0701: return h;
0702: }
0703:
0704: protected static void loadJadManifest(
0705: final AntProjectHelper helper, final File jadManifest)
0706: throws IOException {
0707: final Map<String, String> map = new HashMap<String, String>();
0708: loadJadManifest(map, jadManifest);
0709: loadPropertiesFromMap(helper, map, map);
0710: }
0711:
0712: public static void loadJadManifest(final Map<String, String> map,
0713: final File jadManifest) throws IOException {
0714: if (!jadManifest.exists() || !jadManifest.isFile()
0715: || !jadManifest.canRead())
0716: return;
0717: String ext = jadManifest.getName();
0718: final int index = ext.lastIndexOf('.');
0719: if (index >= 0)
0720: ext = ext.substring(index + 1);
0721: if ("jad".equals(ext.toLowerCase())) //NOI18N
0722: loadJad(map, jadManifest);
0723: else
0724: loadManifest(map, jadManifest);
0725: }
0726:
0727: protected static void loadJadAndManifest(
0728: final AntProjectHelper helper, final File jad,
0729: final File manifest) throws IOException {
0730: final Map<String, String> jadMap = new HashMap<String, String>(), manifestMap = new HashMap<String, String>();
0731: if (jad != null)
0732: loadJad(jadMap, jad);
0733: if (manifest != null)
0734: loadManifest(manifestMap, manifest);
0735: loadPropertiesFromMap(helper, jadMap.isEmpty() ? manifestMap
0736: : jadMap, manifestMap.isEmpty() ? jadMap : manifestMap);
0737: }
0738:
0739: public static void loadJadAndManifest(
0740: final Map<String, String> map, final File jad,
0741: final File manifest) throws IOException {
0742: if (jad != null)
0743: loadJad(map, jad);
0744: if (manifest != null)
0745: loadManifest(map, manifest);
0746: }
0747:
0748: private static void removeInvalidProperties(
0749: final Map<String, String> map) {
0750: map.remove("MIDlet-Jar-RSA-SHA1"); //NOI18N
0751: map.remove("MIDlet-Jar-Size"); //NOI18N
0752: map.remove("MIDlet-Jar-URL"); //NOI18N
0753: map.remove("MicroEdition-Configuration"); //NOI18N
0754: map.remove("MicroEdition-Profile"); //NOI18N
0755: final String CERTIFICATE = "MIDlet-Certificate-{0}-{1}"; //NOI18N
0756: for (int a = 1;; a++) {
0757: int b = 1;
0758: for (;; b++) {
0759: if (map.remove(MessageFormat.format(CERTIFICATE,
0760: new Object[] { Integer.toString(a),
0761: Integer.toString(b) })) == null)
0762: break;
0763: }
0764: if (b <= 1)
0765: break;
0766: }
0767: }
0768:
0769: protected static void setProperties(final AntProjectHelper helper,
0770: final Map map) {
0771: final EditableProperties ep = helper
0772: .getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH);
0773: ep.putAll(map);
0774: helper.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH,
0775: ep);
0776: }
0777:
0778: private static void loadPropertiesFromMap(
0779: final AntProjectHelper helper,
0780: final Map<String, String> jadMap,
0781: final Map<String, String> manifestMap) throws IOException {
0782: final HashMap<String, String> map = new HashMap<String, String>(
0783: jadMap);
0784: map.putAll(manifestMap);
0785: removeInvalidProperties(map);
0786: final EditableProperties ep = helper
0787: .getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH);
0788: final HashMap<String, String> midlets = new HashMap<String, String>();
0789: final HashMap<String, String> apipermissions = new HashMap<String, String>();
0790: final HashMap<String, String> pushregistry = new HashMap<String, String>();
0791: final HashMap<String, String> others = (HashMap<String, String>) DefaultPropertyParsers.MANIFEST_PROPERTY_PARSER
0792: .decode(
0793: ep
0794: .getProperty(DefaultPropertiesDescriptor.MANIFEST_OTHERS),
0795: null, null);
0796: final HashMap<String, String> manifest = new HashMap<String, String>();
0797: final HashMap<String, String> jad = new HashMap<String, String>();
0798: for (final String key : map.keySet()) {
0799: if (key == null)
0800: continue;
0801: final String value = map.get(key);
0802: if (value == null)
0803: continue;
0804: if ("MIDlet-Permissions".equalsIgnoreCase(key)) //NOI18N
0805: apipermissions.put(key, value);
0806: else if ("MIDlet-Permissions-Opt".equalsIgnoreCase(key)) //NOI18N
0807: apipermissions.put(key, value);
0808: else if (isNumberedProperty(key, MIDLET)) //NOI18N
0809: midlets.put(key, value);
0810: else if (isNumberedProperty(key, "MIDlet-Push-")) //NOI18N
0811: pushregistry.put(key, value);
0812: else if (!jadMap.containsKey(key)
0813: && !KNOWN_ATTRIBUTES.contains(key))
0814: manifest.put(key, value);
0815: else if (!manifestMap.containsKey(key)
0816: && !KNOWN_ATTRIBUTES.contains(key))
0817: jad.put(key, value);
0818: else
0819: others.put(key, value);
0820: }
0821: storeManifestProperties(ep,
0822: DefaultPropertiesDescriptor.MANIFEST_MIDLETS, midlets);
0823: storeManifestProperties(ep,
0824: DefaultPropertiesDescriptor.MANIFEST_APIPERMISSIONS,
0825: apipermissions);
0826: storeManifestProperties(ep,
0827: DefaultPropertiesDescriptor.MANIFEST_PUSHREGISTRY,
0828: pushregistry);
0829: storeManifestProperties(ep,
0830: DefaultPropertiesDescriptor.MANIFEST_OTHERS, others);
0831: storeManifestProperties(ep,
0832: DefaultPropertiesDescriptor.MANIFEST_JAD, jad);
0833: storeManifestProperties(ep,
0834: DefaultPropertiesDescriptor.MANIFEST_MANIFEST, manifest);
0835: helper.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH,
0836: ep);
0837: }
0838:
0839: private static boolean isNumberedProperty(final String key,
0840: final String prefix) {
0841: if (!key.startsWith(prefix))
0842: return false;
0843: try {
0844: Integer.parseInt(key.substring(prefix.length()));
0845: return true;
0846: } catch (NumberFormatException e) {
0847: return false;
0848: }
0849: }
0850:
0851: private static void storeManifestProperties(
0852: final EditableProperties ep, final String name,
0853: final HashMap<String, String> map) {
0854: ep.setProperty(name,
0855: DefaultPropertyParsers.MANIFEST_PROPERTY_PARSER.encode(
0856: map, null, null));
0857: }
0858:
0859: private static void loadJad(final Map<String, String> map,
0860: final File jad) throws IOException {
0861: BufferedReader br;
0862: try {
0863: br = new BufferedReader(new InputStreamReader(
0864: new FileInputStream(jad), DEFAULT_ENCODING));
0865: } catch (UnsupportedEncodingException e) {
0866: br = new BufferedReader(new FileReader(jad));
0867: }
0868: try {
0869: for (;;) {
0870: final String readLine = br.readLine();
0871: if (readLine == null)
0872: break;
0873: if ("".equals(readLine)) //NOI18N
0874: continue;
0875: final int colon = readLine.indexOf(':');
0876: if (colon < 0)
0877: continue;
0878: map.put(readLine.substring(0, colon), readLine
0879: .substring(colon + 1).trim());
0880: }
0881: } finally {
0882: br.close();
0883: }
0884: }
0885:
0886: private static void loadManifest(final Map<String, String> map,
0887: final File manifest) throws IOException {
0888: final FileInputStream fis = new FileInputStream(manifest);
0889: try {
0890: final Manifest m = new Manifest(fis);
0891: final Iterator it = m.getEntries().values().iterator();
0892: while (it.hasNext()) {
0893: putAllAsStrings(map, (Attributes) it.next());
0894: }
0895: putAllAsStrings(map, m.getMainAttributes());
0896: map.remove("Manifest-Version"); //NOI18N
0897: map.remove("Created-By"); //NOI18N
0898: } finally {
0899: fis.close();
0900: }
0901: }
0902:
0903: private static void putAllAsStrings(final Map<String, String> map,
0904: final Attributes attrs) {
0905: for (final Map.Entry en : attrs.entrySet()) {
0906: map.put(en.getKey().toString(), (String) en.getValue());
0907: }
0908: }
0909:
0910: protected static void loadSettingFromSuite(
0911: final AntProjectHelper helper, final File suite)
0912: throws IOException {
0913: final Document doc = getDocumentForSuite(suite);
0914: loadSettingFromSuite(helper, doc);
0915: }
0916:
0917: public static Document getDocumentForSuite(final File suite)
0918: throws IOException {
0919: if (suite == null || !suite.exists() || !suite.isFile()
0920: || !suite.canRead())
0921: return null;
0922: final InputStream is = new FileInputStream(suite);
0923: Document doc = null;
0924: try {
0925: doc = XMLUtil.parse(new InputSource(is), false, false,
0926: new ErrorHandler() {
0927: public void error(SAXParseException e)
0928: throws SAXException {
0929: throw new SAXException(e);
0930: }
0931:
0932: public void fatalError(SAXParseException e)
0933: throws SAXException {
0934: throw new SAXException(e);
0935: }
0936:
0937: public void warning(@SuppressWarnings("unused")
0938: SAXParseException e) {
0939: }
0940: }, null);
0941: } catch (SAXException e) {
0942: DialogDisplayer.getDefault().notify(
0943: new NotifyDescriptor.Message(NbBundle.getMessage(
0944: J2MEProjectGenerator.class,
0945: "MSG_ProjectGen_CannotParseSuite"))); //NOI18N
0946: return null;
0947: } finally {
0948: try {
0949: is.close();
0950: } catch (IOException e) {
0951: }
0952: }
0953: return doc;
0954: }
0955:
0956: private static void loadSettingFromSuite(
0957: final AntProjectHelper helper, final Document doc)
0958: throws IOException {
0959: if (doc == null)
0960: return;
0961:
0962: final EditableProperties ep = helper
0963: .getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH);
0964: final HashMap<String, String> midlets = new HashMap<String, String>();
0965: final HashMap<String, String> pushregistry = new HashMap<String, String>();
0966: final HashSet<String> permission = new HashSet<String>();
0967: final HashSet<String> permissionOpt = new HashSet<String>();
0968: final HashMap<String, String> apipermissions = new HashMap<String, String>();
0969: final HashMap<String, String> others = (HashMap<String, String>) DefaultPropertyParsers.MANIFEST_PROPERTY_PARSER
0970: .decode(
0971: ep
0972: .getProperty(DefaultPropertiesDescriptor.MANIFEST_OTHERS),
0973: null, null);
0974: Profile configuration = null, profile = null;
0975:
0976: final Node root = doc.getFirstChild();
0977: if ("2.0".equals(getAttributeValue(root, "version"))) { //NOI18N
0978: Node node = root.getFirstChild();
0979: while (node != null) {
0980: if ("attribute".equalsIgnoreCase(node.getNodeName())) { //NOI18N
0981: Node attributeNode = node.getFirstChild();
0982: while (attributeNode != null) {
0983: if ("midlet".equalsIgnoreCase(attributeNode
0984: .getNodeName())) { //NOI18N
0985: final String order = getAttributeValue(
0986: attributeNode, "order"); //NOI18N
0987: final String clazz = getAttributeValue(
0988: attributeNode, "class"); //NOI18N
0989: final String icon = getAttributeValue(
0990: attributeNode, "icon"); //NOI18N
0991: final String name = getAttributeValue(
0992: attributeNode, NAME); //NOI18N
0993: if (order != null && clazz != null
0994: && icon != null && name != null)
0995: midlets.put(MIDLET + order, name + ", "
0996: + icon + ", " + clazz); //NOI18N
0997: } else if ("permission"
0998: .equalsIgnoreCase(attributeNode
0999: .getNodeName())) { //NOI18N
1000: final String name = getAttributeValue(
1001: attributeNode, NAME); //NOI18N
1002: if (name != null)
1003: permission.add(name);
1004: } else if ("permission-opt"
1005: .equalsIgnoreCase(attributeNode
1006: .getNodeName())) { //NOI18N
1007: final String name = getAttributeValue(
1008: attributeNode, NAME); //NOI18N
1009: if (name != null)
1010: permissionOpt.add(name);
1011: } else if ("required"
1012: .equalsIgnoreCase(attributeNode
1013: .getNodeName())
1014: || //NOI18N
1015: "optional"
1016: .equalsIgnoreCase(attributeNode
1017: .getNodeName()) || //NOI18N
1018: "user".equalsIgnoreCase(attributeNode
1019: .getNodeName()) || //NOI18N
1020: "security"
1021: .equalsIgnoreCase(attributeNode
1022: .getNodeName())) { //NOI18N
1023: final String name = getAttributeValue(
1024: attributeNode, NAME); //NOI18N
1025: final String value = getAttributeValue(
1026: attributeNode, "value"); //NOI18N
1027: if (name != null && value != null)
1028: others.put(name, value);
1029: } else if ("push"
1030: .equalsIgnoreCase(attributeNode
1031: .getNodeName())) { //NOI18N
1032: final String protocol = getAttributeValue(
1033: attributeNode, "protocol"); //NOI18N
1034: final String host = getAttributeValue(
1035: attributeNode, "host"); //NOI18N
1036: final String clazz = getAttributeValue(
1037: attributeNode, "class"); //NOI18N
1038: final String order = getAttributeValue(
1039: attributeNode, "order"); //NOI18N
1040: if (protocol != null && host != null
1041: && clazz != null && order != null)
1042: midlets.put("MIDlet-Push-" + order,
1043: protocol + ", " + clazz + ", "
1044: + host); //NOI18N
1045: }
1046: attributeNode = attributeNode.getNextSibling();
1047: }
1048: } else if ("Configuration".equalsIgnoreCase(node
1049: .getNodeName())) { //NOI18N
1050: configuration = name2profile(getAttributeValue(
1051: node, "value")); //NOI18N
1052: } else if ("Profile".equalsIgnoreCase(node
1053: .getNodeName())) { //NOI18N
1054: profile = name2profile(getAttributeValue(node,
1055: "value")); //NOI18N
1056: }
1057: node = node.getNextSibling();
1058: }
1059: }
1060:
1061: if (!permission.isEmpty())
1062: apipermissions.put("MIDlet-Permissions",
1063: hashMapToCommaSeparatedString(permission)); //NOI18N
1064: if (!permissionOpt.isEmpty())
1065: apipermissions.put("MIDlet-Permissions-Opt",
1066: hashMapToCommaSeparatedString(permissionOpt)); //NOI18N
1067: storeManifestProperties(ep,
1068: DefaultPropertiesDescriptor.MANIFEST_MIDLETS, midlets);
1069: storeManifestProperties(ep,
1070: DefaultPropertiesDescriptor.MANIFEST_APIPERMISSIONS,
1071: apipermissions);
1072: storeManifestProperties(ep,
1073: DefaultPropertiesDescriptor.MANIFEST_PUSHREGISTRY,
1074: pushregistry);
1075: removeInvalidProperties(others);
1076: storeManifestProperties(ep,
1077: DefaultPropertiesDescriptor.MANIFEST_OTHERS, others);
1078: if (configuration != null || profile != null) {
1079: Profile profiles[] = new Profile[configuration == null
1080: || profile == null ? 1 : 2];
1081: profiles[0] = configuration;
1082: if (profile != null)
1083: profiles[profiles.length - 1] = profile;
1084: final J2MEPlatform platform = findPlatform(profiles);
1085: if (platform != null)
1086: ep.putAll(PlatformConvertor.extractPlatformProperties(
1087: "", platform, null, configuration.toString(),
1088: profile.toString())); //NOI18N
1089: }
1090: helper.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH,
1091: ep);
1092: }
1093:
1094: private static String hashMapToCommaSeparatedString(
1095: final HashSet<String> set) {
1096: final StringBuffer res = new StringBuffer();
1097: boolean first = true;
1098: for (final String o : set) {
1099: if (o == null)
1100: continue;
1101: res.append(o);
1102: if (!first)
1103: res.append(", "); //NOI18N
1104: else
1105: first = false;
1106: }
1107: return res.toString();
1108: }
1109:
1110: public static String getAttributeValue(Node node, final String attr) {
1111: try {
1112: if (node == null)
1113: return null;
1114: node = node.getAttributes().getNamedItem(attr);
1115: if (node == null)
1116: return null;
1117: return node.getNodeValue();
1118: } catch (DOMException e) {
1119: return null;
1120: }
1121: }
1122:
1123: public static File findWtkJadFile(final String appLocation) {
1124: if (appLocation == null)
1125: return null;
1126: File jad = null;
1127: final File bin = new File(appLocation, "bin"); //NOI18N
1128: if (bin.exists() && bin.isDirectory() && bin.canRead()) {
1129: final File[] files = bin.listFiles();
1130: jad = Utils.findSubFile(files, new File(appLocation)
1131: .getName()
1132: + ".jad"); //NOI18N
1133: if (jad == null)
1134: jad = Utils.findAnyFile(files, "jad"); //NOI18N
1135: }
1136: return jad;
1137: }
1138:
1139: public static File findWtkManifestFile(final String appLocation) {
1140: if (appLocation == null)
1141: return null;
1142: File mf = null;
1143: final File bin = new File(appLocation, "bin"); //NOI18N
1144: if (bin.exists() && bin.isDirectory() && bin.canRead()) {
1145: final File[] files = bin.listFiles();
1146: mf = Utils.findSubFile(files, "manifest.mf"); //NOI18N
1147: if (mf == null)
1148: mf = Utils.findAnyFile(files, "mf"); //NOI18N
1149: }
1150: return mf;
1151: }
1152:
1153: protected static void loadWTKProperties(
1154: final AntProjectHelper helper, final File wtkProject)
1155: throws IOException {
1156: final File propFile = new File(wtkProject, "project.properties"); //NOI18N
1157: if (!propFile.exists() || !propFile.isFile())
1158: return;
1159: final Properties props = new Properties();
1160: FileInputStream fis = null;
1161: try {
1162: fis = new FileInputStream(propFile);
1163: props.load(fis);
1164: } finally {
1165: if (fis != null)
1166: try {
1167: fis.close();
1168: } catch (IOException e) {
1169: }
1170: }
1171: final Profile configuration = wtkName2profile(props
1172: .getProperty("configuration"), "CLDC"); //NOI18N
1173: if (configuration != null) {
1174: final J2MEPlatform found = findPlatform(new Profile[] { configuration });
1175: if (found != null) {
1176: final EditableProperties ep = helper
1177: .getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH);
1178: ep.putAll(PlatformConvertor
1179: .extractPlatformProperties("", found, null,
1180: configuration.toString(), null)); //NOI18N
1181: helper.putProperties(
1182: AntProjectHelper.PROJECT_PROPERTIES_PATH, ep);
1183: }
1184: }
1185: }
1186:
1187: private static Profile wtkName2profile(String profile,
1188: final String prefix) {
1189: if (profile == null)
1190: return null;
1191: if (profile.startsWith(prefix)) {
1192: profile = profile.substring(prefix.length());
1193: if (profile.startsWith("-")) //NOI18N
1194: profile = profile.substring(1);
1195: profile = prefix + "-" + profile; //NOI18N
1196: }
1197: return name2profile(profile);
1198: }
1199:
1200: private static Profile name2profile(final String name) {
1201: if (name == null)
1202: return null;
1203: final int i = name.indexOf('-');
1204: try {
1205: if (i >= 0)
1206: return new Profile(name.substring(0, i),
1207: new SpecificationVersion(name.substring(i + 1)));
1208: return new Profile(name, new SpecificationVersion("1.0")); //NOI18N
1209: } catch (NumberFormatException e) {
1210: return null;
1211: }
1212: }
1213:
1214: public static J2MEPlatform findPlatform(final Profile[] profiles) {
1215: JavaPlatform p[];
1216: if (profiles != null)
1217: p = JavaPlatformManager.getDefault().getPlatforms(
1218: null,
1219: new Specification(J2MEPlatform.SPECIFICATION_NAME,
1220: null, profiles));
1221: else
1222: p = JavaPlatformManager.getDefault().getPlatforms(
1223: null,
1224: new Specification(J2MEPlatform.SPECIFICATION_NAME,
1225: null));
1226:
1227: for (int i = 0; i < p.length; i++) {
1228: if (p[i] instanceof J2MEPlatform) {
1229: return (J2MEPlatform) p[i];
1230: }
1231: }
1232: return null;
1233: }
1234:
1235: private static FileObject createProjectLocation(File dir)
1236: throws IOException {
1237: dir = dir.getCanonicalFile();
1238: File rootF = dir;
1239: while (rootF != null
1240: && !(rootF = rootF.getParentFile()).exists())
1241: ;
1242: if (rootF == null)
1243: throw new IOException("Cannot find existing parent from "
1244: + dir.toString()); //NOI18N
1245: FileObject dirFO = FileUtil.toFileObject(FileUtil
1246: .normalizeFile(rootF));
1247: assert dirFO != null : "FileObject for " + rootF
1248: + "does not exist !"; //NOI18N
1249: if (rootF != dir) {
1250: String relName = dir.getAbsolutePath().substring(
1251: rootF.getAbsolutePath().length());
1252: if (relName.startsWith(File.separator))
1253: relName = relName.substring(1);
1254: dirFO = FileUtil.createFolder(dirFO, relName);
1255: }
1256: dirFO.refresh(false); // workaround for #5037460
1257: assert dirFO.isFolder() : "Not really a dir: " + dir; //NOI18N
1258: // assert dirFO.getChildren().length == 0 : "Dir must have been empty: " + dir;
1259: File parent = FileUtil.toFile(dirFO);
1260: if (parent != null)
1261: parent = parent.getParentFile();
1262: if (parent != null)
1263: ProjectChooser.setProjectsFolder(parent);
1264: return dirFO;
1265: }
1266:
1267: public static void copyJavaFolder(final File source,
1268: final File target, final Pattern filter) throws IOException {
1269: copyJavaFolder(source, target, target, filter);
1270: }
1271:
1272: private static void copyJavaFolder(final File source,
1273: final File targetRoot, final File target,
1274: final Pattern filter) throws IOException {
1275: if (source == null || targetRoot == null || target == null)
1276: return;
1277: if (isParent(source, target))
1278: return;
1279: final File[] files = source.listFiles();
1280: if (files != null)
1281: for (int a = 0; a < files.length; a++) {
1282: final File file = files[a];
1283: if (filter.matcher(
1284: file.getAbsolutePath().replace('\\', '/'))
1285: .matches())
1286: continue;
1287: if (file.isDirectory()) {
1288: final File subdir = new File(target, file.getName());
1289: subdir.mkdirs();
1290: copyJavaFolder(file, targetRoot, subdir, filter);
1291: } else {
1292: File targetFile = new File(target, file.getName());
1293: if (file.getName().toLowerCase().endsWith(".java")) { //NOI18N
1294: String classPackage = null;
1295: BufferedReader br = null;
1296: try {
1297: br = new BufferedReader(
1298: new FileReader(file));
1299: for (;;) {
1300: final String line = br.readLine();
1301: if (line == null)
1302: break;
1303:
1304: int pos = 0;
1305: while (pos < line.length()
1306: && line.charAt(pos) == ' ')
1307: pos++;
1308: if (!line.startsWith("package", pos)) //NOI18N
1309: continue;
1310: pos += "package".length(); //NOI18N
1311: final int tmppos = pos;
1312: while (pos < line.length()
1313: && line.charAt(pos) == ' ')
1314: pos++;
1315: if (tmppos == pos)
1316: continue;
1317: int end = pos;
1318: while (end < line.length()
1319: && (Character
1320: .isJavaIdentifierPart(line
1321: .charAt(end)) || line
1322: .charAt(end) == '.'))
1323: end++;
1324: if (end == pos)
1325: continue;
1326: if (end < line.length()
1327: && !Character.isWhitespace(line
1328: .charAt(end))
1329: && line.charAt(end) != ';')
1330: continue;
1331: classPackage = line.substring(pos, end);
1332: break;
1333: }
1334: } catch (IOException e) {
1335: } finally {
1336: if (br != null)
1337: try {
1338: br.close();
1339: } catch (IOException e) {
1340: }
1341: }
1342: if (classPackage != null
1343: && !"".equals(classPackage)) { //NOI18N
1344: final File dir = new File(targetRoot,
1345: classPackage.replace('.',
1346: File.separatorChar));
1347: dir.mkdirs();
1348: targetFile = new File(dir, file.getName());
1349: }
1350: }
1351: FileInputStream fis = null;
1352: FileOutputStream fos = null;
1353: try {
1354: fis = new FileInputStream(file);
1355: fos = new FileOutputStream(targetFile);
1356: FileUtil.copy(fis, fos);
1357: } finally {
1358: if (fis != null)
1359: try {
1360: fis.close();
1361: } catch (IOException e) {
1362: }
1363: if (fos != null)
1364: try {
1365: fos.close();
1366: } catch (IOException e) {
1367: }
1368: }
1369: }
1370: }
1371: }
1372:
1373: private static boolean isParent(final File source, File target) {
1374: while (target != null) {
1375: if (source.equals(target))
1376: return true;
1377: target = target.getParentFile();
1378: }
1379: return false;
1380: }
1381:
1382: protected static void unzip(final InputStream source,
1383: final File targetFolder) throws IOException {
1384: //installation
1385: final ZipInputStream zip = new ZipInputStream(source);
1386: try {
1387: ZipEntry ent;
1388: while ((ent = zip.getNextEntry()) != null) {
1389: final File f = new File(targetFolder, ent.getName());
1390: if (ent.isDirectory()) {
1391: f.mkdirs();
1392: } else {
1393: f.getParentFile().mkdirs();
1394: final FileOutputStream out = new FileOutputStream(f);
1395: try {
1396: FileUtil.copy(zip, out);
1397: } finally {
1398: out.close();
1399: }
1400: }
1401: }
1402: } finally {
1403: zip.close();
1404: }
1405: }
1406:
1407: protected static void deleteAll(final File directory) {
1408: final File[] files = directory.listFiles();
1409: for (int a = 0; a < files.length; a++) {
1410: final File file = files[a];
1411: if (file.isDirectory())
1412: deleteAll(file);
1413: else
1414: file.delete();
1415: }
1416: directory.delete();
1417: }
1418:
1419: public static void loadLibraries(final AntProjectHelper h,
1420: final ReferenceHelper refHelper, final File[] files) {
1421: StringBuffer libs = null;
1422: if (files != null)
1423: for (int a = 0; a < files.length; a++) {
1424: if (files[a] == null || !files[a].exists())
1425: continue;
1426: final String name = files[a].getName().toLowerCase();
1427: if (files[a].isFile() && !name.endsWith(".jar")
1428: && !name.endsWith(".zip")) //NOI18N
1429: continue;
1430: if (libs != null)
1431: libs.append(File.pathSeparatorChar);
1432: else
1433: libs = new StringBuffer();
1434: libs.append(refHelper.createForeignFileReference(
1435: FileUtil.normalizeFile(files[a]), "anyfile")); //NOI18N
1436: }
1437: if (libs == null)
1438: return;
1439: final EditableProperties ep = h
1440: .getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH);
1441: ep.put(DefaultPropertiesDescriptor.LIBS_CLASSPATH, libs
1442: .toString());
1443: h.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH, ep);
1444: }
1445:
1446: public static void copyMIDletProperty(final Project project,
1447: final AntProjectHelper h, String sourceClass,
1448: String targetClass) throws IOException {
1449: if (sourceClass == null || targetClass == null)
1450: return;
1451:
1452: final ProjectConfigurationsHelper confHelper = project
1453: .getLookup().lookup(ProjectConfigurationsHelper.class);
1454: final ProjectConfiguration[] confs = confHelper
1455: .getConfigurations().toArray(
1456: new ProjectConfiguration[0]);
1457: final EditableProperties ep = h
1458: .getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH);
1459:
1460: final String defaultValue = ep
1461: .getProperty(DefaultPropertiesDescriptor.MANIFEST_MIDLETS);
1462: HashMap<String, String> map = defaultValue != null ? (HashMap<String, String>) DefaultPropertyParsers.MANIFEST_PROPERTY_PARSER
1463: .decode(defaultValue, null, null)
1464: : new HashMap<String, String>();
1465:
1466: copyMIDletProperty(map, sourceClass, targetClass);
1467:
1468: ep.put(DefaultPropertiesDescriptor.MANIFEST_MIDLETS,
1469: DefaultPropertyParsers.MANIFEST_PROPERTY_PARSER.encode(
1470: map, null, null));
1471:
1472: for (int i = 0; i < confs.length; i++) {
1473: final ProjectConfiguration conf = confs[i];
1474: final String confName = conf.getDisplayName();
1475: final String propertyName = VisualPropertySupport
1476: .translatePropertyName(
1477: confName,
1478: DefaultPropertiesDescriptor.MANIFEST_MIDLETS,
1479: false);
1480: if (propertyName == null)
1481: continue;
1482: final String propertyValue = ep.getProperty(propertyName);
1483: if (propertyValue == null)
1484: continue;
1485: map = (HashMap<String, String>) DefaultPropertyParsers.MANIFEST_PROPERTY_PARSER
1486: .decode(defaultValue, null, null);
1487:
1488: copyMIDletProperty(map, sourceClass, targetClass);
1489:
1490: ep.put(propertyName,
1491: DefaultPropertyParsers.MANIFEST_PROPERTY_PARSER
1492: .encode(map, null, null));
1493: }
1494:
1495: h.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH, ep);
1496: }
1497:
1498: private static void copyMIDletProperty(HashMap<String, String> map,
1499: String sourceClass, String targetClass) {
1500: String newMIDlet = null;
1501: int a = 1;
1502: for (;;) {
1503: String value = map.get(MIDLET + a);// NOI18N
1504: if (value == null)
1505: break;
1506: int index = value.lastIndexOf(',');
1507: if (index >= 0
1508: && sourceClass.equals(value.substring(index + 1)
1509: .trim()))
1510: newMIDlet = value.substring(0, index + 1) + targetClass;
1511: a++;
1512: }
1513: if (newMIDlet != null)
1514: map.put(MIDLET + a, newMIDlet); //NOI18N
1515: }
1516:
1517: public static void addMIDletProperty(final Project project,
1518: final AntProjectHelper h, String name, String clazz,
1519: String icon) throws IOException {
1520: if (name == null)
1521: name = ""; // NOI18N
1522: if (clazz == null)
1523: clazz = ""; // NOI18N
1524: if (icon == null)
1525: icon = ""; // NOI18N
1526:
1527: final ProjectConfigurationsHelper confHelper = project
1528: .getLookup().lookup(ProjectConfigurationsHelper.class);
1529: final ProjectConfiguration[] confs = confHelper
1530: .getConfigurations().toArray(
1531: new ProjectConfiguration[0]);
1532: final EditableProperties ep = h
1533: .getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH);
1534:
1535: final String defaultValue = ep
1536: .getProperty(DefaultPropertiesDescriptor.MANIFEST_MIDLETS);
1537: HashMap<String, String> map = defaultValue != null ? (HashMap<String, String>) DefaultPropertyParsers.MANIFEST_PROPERTY_PARSER
1538: .decode(defaultValue, null, null)
1539: : new HashMap<String, String>();
1540: addMIDletProperty(map, name, clazz, icon);
1541: ep.put(DefaultPropertiesDescriptor.MANIFEST_MIDLETS,
1542: DefaultPropertyParsers.MANIFEST_PROPERTY_PARSER.encode(
1543: map, null, null));
1544:
1545: for (int i = 0; i < confs.length; i++) {
1546: final ProjectConfiguration conf = confs[i];
1547: final String confName = conf.getDisplayName();
1548: final String propertyName = VisualPropertySupport
1549: .translatePropertyName(
1550: confName,
1551: DefaultPropertiesDescriptor.MANIFEST_MIDLETS,
1552: false);
1553: if (propertyName == null)
1554: continue;
1555: final String propertyValue = ep.getProperty(propertyName);
1556: if (propertyValue == null)
1557: continue;
1558: map = (HashMap<String, String>) DefaultPropertyParsers.MANIFEST_PROPERTY_PARSER
1559: .decode(defaultValue, null, null);
1560: addMIDletProperty(map, name, clazz, icon);
1561: ep.put(propertyName,
1562: DefaultPropertyParsers.MANIFEST_PROPERTY_PARSER
1563: .encode(map, null, null));
1564: }
1565:
1566: h.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH, ep);
1567: }
1568:
1569: private static void addMIDletProperty(
1570: final Map<String, String> map, final String name,
1571: final String clazz, final String icon) {
1572: int a = 1;
1573: while (map.containsKey(MIDLET + a))
1574: //NOI18N
1575: a++;
1576: map.put(MIDLET + a, name + ", " + icon + ", " + clazz); //NOI18N
1577: }
1578:
1579: public static void refreshProject(final FileObject projectLocation,
1580: final FileObject srcLocation) {
1581: if (projectLocation != null)
1582: projectLocation.refresh(false);
1583: if (srcLocation != null)
1584: srcLocation.refresh();
1585: }
1586:
1587: protected static void fillMissingMIDlets(final Project project,
1588: final AntProjectHelper helper) {
1589: final ReferenceHelper refHelper = project.getLookup().lookup(
1590: ReferenceHelper.class);
1591: final ProjectConfigurationsHelper confHelper = project
1592: .getLookup().lookup(ProjectConfigurationsHelper.class);
1593: final MIDletScanner scanner = MIDletScanner
1594: .getDefault(new J2MEProjectProperties(project, helper,
1595: refHelper, confHelper));
1596: final DefaultComboBoxModel midlets = new DefaultComboBoxModel();
1597: scanner.scan(midlets, null, null, new ChangeListener() {
1598:
1599: public void stateChanged(@SuppressWarnings("unused")
1600: ChangeEvent e) {
1601: final MIDletsCacheHelper mHelper = project.getLookup()
1602: .lookup(MIDletsCacheHelper.class);
1603:
1604: for (int i = 0; i < midlets.getSize(); i++)
1605: try {
1606: final String midlet = (String) midlets
1607: .getElementAt(i);
1608:
1609: if (!mHelper.contains(midlet))
1610: addMIDletProperty(project, helper,
1611: midlet.substring(midlet
1612: .lastIndexOf('.') + 1),
1613: midlet, null);
1614: } catch (IOException ioe) {
1615: }
1616: if (project instanceof J2MEProject)
1617: ((J2MEProject) project).hookNewProjectCreated();
1618: try {
1619: ProjectManager.getDefault().saveProject(project);
1620: } catch (IOException ioe) {
1621: }
1622: }
1623: });
1624: }
1625:
1626: protected static void setSourceRoot(final AntProjectHelper helper,
1627: final ReferenceHelper refHelper, final String srcRoot) {
1628: String ref = refHelper.createForeignFileReference(helper
1629: .resolveFile(srcRoot), "anyfile");
1630: final EditableProperties ep = helper
1631: .getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH);
1632: ep.put(DefaultPropertiesDescriptor.SRC_DIR, ref); //NOI18N
1633: helper.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH,
1634: ep);
1635: refreshProject(helper.getProjectDirectory(), helper
1636: .resolveFileObject(srcRoot));
1637: }
1638:
1639: protected static ReferenceHelper getReferenceHelper(final Project p) {
1640: return p.getLookup().lookup(ReferenceHelper.class);
1641: }
1642: }
|