001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.mobility.cldcplatform;
043:
044: import java.io.File;
045: import java.io.IOException;
046: import java.net.MalformedURLException;
047: import java.net.URL;
048: import java.text.MessageFormat;
049: import java.util.ArrayList;
050: import java.util.Arrays;
051: import java.util.Collection;
052: import java.util.Collections;
053: import java.util.HashMap;
054: import java.util.HashSet;
055: import java.util.List;
056: import java.util.Map;
057: import java.util.Set;
058: import java.util.StringTokenizer;
059:
060: import org.netbeans.api.java.classpath.ClassPath;
061: import org.netbeans.api.java.platform.JavaPlatform;
062: import org.netbeans.api.java.platform.Profile;
063: import org.netbeans.api.java.platform.Specification;
064: import org.netbeans.spi.java.classpath.PathResourceImplementation;
065: import org.netbeans.spi.java.classpath.support.ClassPathSupport;
066: import org.netbeans.spi.project.support.ant.PropertyUtils;
067: import org.openide.filesystems.FileObject;
068: import org.openide.filesystems.FileUtil;
069: import org.openide.filesystems.Repository;
070: import org.openide.filesystems.URLMapper;
071: import org.openide.loaders.DataFolder;
072: import org.openide.loaders.DataObject;
073: import org.openide.modules.SpecificationVersion;
074: import org.openide.util.NbBundle;
075: import org.openide.util.Utilities;
076:
077: /**
078: * Implementation of the JavaPlatform API class, which serves proper
079: * bootstrap classpath information.
080: */
081: public final class J2MEPlatform extends JavaPlatform {
082:
083: public static final String SPECIFICATION_NAME = "j2me"; // NOI18N
084: private static final String URL_SEPARATOR = ","; // NOI18N
085: private static final String PATH_SEPARATOR = ":"; // NOI18N
086: public static final String PLATFORM_STRING_PREFIX = "${platform.home}/"; // NOI18N
087:
088: private ClassPath bootstrapLibs, standardLibs;
089: private Specification spec;
090:
091: private String name;
092: private final String type;
093: private String preverifyCmd;
094: private String runCmd;
095: private String debugCmd;
096: private Device[] devices;
097: private final File homeFile;
098: private FileObject home;
099: private String displayName;
100: private List<URL> javadocs;
101: private ClassPath sources;
102:
103: public J2MEPlatform(String name, String home, String type,
104: String displayName, String srcPath, String docPath,
105: String preverifyCmd, String runCmd, String debugCmd,
106: Device[] devices) {
107: assert name != null;
108: this .name = name;
109: assert home != null;
110: this .homeFile = FileUtil.normalizeFile(new File(home));
111: this .home = FileUtil.toFileObject(homeFile);
112: assert type != null;
113: this .type = type;
114: this .displayName = displayName == null ? name : displayName;
115: this .preverifyCmd = preverifyCmd;
116: this .runCmd = runCmd;
117: this .debugCmd = debugCmd;
118: assert devices != null;
119: assert devices.length > 0;
120: this .devices = devices;
121: this .sources = ClassPathSupport
122: .createClassPath(resolveRelativePathToFileObjects(
123: srcPath).toArray(new FileObject[0]));
124: this .javadocs = resolveRelativePathToURLs(docPath);
125: }
126:
127: public Device[] getDevices() {
128: return devices == null ? null : devices.clone();
129: }
130:
131: public synchronized void setDevices(final Device[] devices) {
132: this .devices = devices;
133: spec = null;
134: bootstrapLibs = ClassPathSupport
135: .createClassPath(getAllLibraries());
136: firePropertyChange("devices", null, null); //NOI18N
137: firePropertyChange("bootstrapLibraries", null, null); //NOI18N
138: }
139:
140: private List<URL> resolveRelativePathToURLs(final String path) {
141: final List<URL> array = new ArrayList<URL>();
142: if (path == null)
143: return array;
144: final StringTokenizer stk = new StringTokenizer(path,
145: URL_SEPARATOR);
146: while (stk.hasMoreTokens()) {
147: final URL url = resolveRelativePathToURL(stk.nextToken()
148: .trim());
149: if (url != null)
150: array.add(url);
151: }
152: return array;
153: }
154:
155: private URL getURL(final String fragment)
156: throws MalformedURLException {
157: try {
158: final URL url = new URL(fragment);
159: if (fragment.equals(url.toExternalForm())) {
160: return url;
161: }
162: } catch (MalformedURLException e) {
163: }
164: return (fragment.startsWith(PLATFORM_STRING_PREFIX) ? new File(
165: homeFile, fragment.substring(PLATFORM_STRING_PREFIX
166: .length())) : new File(fragment)).toURI()
167: .toURL();
168: }
169:
170: public URL resolveRelativePathToURL(final String path) {
171: if (path == null || path.length() <= 0)
172: return null;
173: try {
174: final URL url = getURL(path);
175: if (!FileUtil.isArchiveFile(url)) {
176: final String s = url.toExternalForm();
177: if (s.endsWith("/"))
178: return url; //NOI18N
179: return new URL(s + '/');
180: }
181: return FileUtil.getArchiveRoot(url);
182: } catch (MalformedURLException e) {
183: e.printStackTrace();
184: return null;
185: }
186: }
187:
188: public static URL localfilepath2url(final String path) {
189: try {
190: return new File(path).toURI().toURL();
191: } catch (MalformedURLException e) {
192: e.printStackTrace();
193: return null;
194: }
195: }
196:
197: public static URL localfilepath2url(final File file) {
198: try {
199: return file.toURI().toURL();
200: } catch (MalformedURLException e) {
201: e.printStackTrace();
202: return null;
203: }
204: }
205:
206: private List<FileObject> resolveRelativePathToFileObjects(
207: final String path) {
208: final ArrayList<FileObject> res = new ArrayList<FileObject>();
209: if (path == null)
210: return new ArrayList<FileObject>();
211: final String paths[] = PropertyUtils.tokenizePath(path);
212: for (int a = 0; a < paths.length; a++) {
213: final FileObject fo = resolveRelativePathToFileObject(paths[a]
214: .trim());
215: if (fo != null)
216: res.add(fo);
217: }
218: return res;
219: }
220:
221: public FileObject resolveRelativePathToFileObject(final String path) {
222: if (path == null || path.length() <= 0)
223: return null;
224: File f;
225: if (path.startsWith(PLATFORM_STRING_PREFIX))
226: f = new File(homeFile, path
227: .substring(PLATFORM_STRING_PREFIX.length()));
228: else
229: f = new File(path);
230: f = FileUtil.normalizeFile(f);
231: final FileObject fo = FileUtil.toFileObject(f);
232: if (fo == null || !FileUtil.isArchiveFile(fo))
233: return fo;
234: return FileUtil.getArchiveRoot(fo);
235: }
236:
237: public static String getFilePath(final FileObject fo) {
238: if (fo == null)
239: return null;
240: FileObject ff = FileUtil.getArchiveFile(fo);
241: if (ff == null)
242: ff = fo;
243: final File file = FileUtil.toFile(ff);
244: return (file != null) ? file.getAbsolutePath() : null;
245: }
246:
247: public String getAllLibrariesString() {
248: final FileObject[] files = getAllLibraries();
249: if (files == null || files.length <= 0)
250: return ""; //NOI18N
251: final StringBuffer sb = new StringBuffer();
252: boolean first = true;
253: for (int a = 0; a < files.length; a++) {
254: final String value = getFilePath(files[a]);
255: if (value == null) {
256: continue;
257: }
258: if (first)
259: first = false;
260: else
261: sb.append(':'); //NOI18N
262: sb.append(value);
263: }
264: return sb.toString();
265: }
266:
267: /**
268: * implements JavaPlatform
269: * @return empty ClassPath
270: */
271: public ClassPath getStandardLibraries() {
272: if (standardLibs == null) {
273: standardLibs = ClassPathSupport
274: .createClassPath(new ArrayList<PathResourceImplementation>());
275: }
276: return standardLibs;
277: }
278:
279: /**
280: * implements JavaPlatform
281: * @return complete ClassPath over all APIs and all devices
282: */
283: public ClassPath getBootstrapLibraries() {
284: if (bootstrapLibs == null) {
285: bootstrapLibs = ClassPathSupport
286: .createClassPath(getAllLibraries());
287: }
288: return bootstrapLibs;
289: }
290:
291: private FileObject[] getAllLibraries() {
292: final HashSet<FileObject> fobs = new HashSet<FileObject>();
293: for (int i = 0; i < devices.length; i++) {
294: final J2MEProfile[] profiles = devices[i].getProfiles();
295: for (int j = 0; j < profiles.length; j++) {
296: fobs
297: .addAll(resolveRelativePathToFileObjects(profiles[j]
298: .getClassPath()));
299: }
300: }
301: return fobs.toArray(new FileObject[fobs.size()]);
302: }
303:
304: public String getDisplayName() {
305: return displayName;
306: }
307:
308: public void setDisplayName(final String displayName) {
309: this .displayName = displayName;
310: }
311:
312: public void setName(final String name) {
313: this .name = name;
314: }
315:
316: public String toString() {
317: return getDisplayName();
318: }
319:
320: public String getVendor() {
321: return displayName;
322: }
323:
324: public String getName() {
325: return name;
326: }
327:
328: public String getType() {
329: return type;
330: }
331:
332: /**
333: * Getter for property preverifyCmd.
334: *
335: * @return Value of property preverifyCmd.
336: */
337: public String getPreverifyCmd() {
338: return this .preverifyCmd;
339: }
340:
341: /**
342: * Getter for property runCmd.
343: *
344: * @return Value of property runCmd.
345: */
346: public String getRunCmd() {
347: return this .runCmd;
348: }
349:
350: /**
351: * Getter for property debugCmd.
352: *
353: * @return Value of property debugCmd.
354: */
355: public String getDebugCmd() {
356: return this .debugCmd;
357: }
358:
359: public String getHomePath() {
360: return homeFile.getAbsolutePath();
361: }
362:
363: public Collection<FileObject> getInstallFolders() {
364: if (home == null)
365: home = FileUtil.toFileObject(homeFile);
366: return home != null && home.isValid() && home.isFolder() ? Collections
367: .singleton(home)
368: : Collections.EMPTY_SET;
369: }
370:
371: public List<URL> getJavadocFolders() {
372: return Collections.unmodifiableList(javadocs);
373: }
374:
375: public void setJavadocFolders(final List<URL> javadocs) {
376: this .javadocs = new ArrayList<URL>(javadocs);
377: firePropertyChange("javadocFolders", null, null); //NOI18N
378: }
379:
380: private String toRelativePaths(final List<? extends Object> path) {
381: final StringBuffer sb = new StringBuffer();
382: String homePath = homeFile.getAbsolutePath();
383: if (Utilities.isWindows())
384: homePath = "/" + homePath.toLowerCase().replace('\\', '/'); //NOI18N
385: for (final Object o : path) {
386: if (o instanceof FileObject) {
387: FileObject fo = FileUtil.getArchiveFile((FileObject) o);
388: if (fo == null)
389: fo = (FileObject) o;
390: if (home != null && FileUtil.isParentOf(home, fo)) {
391: String tmp = FileUtil.getRelativePath(home, fo);
392: if (tmp != null) {
393: if (tmp.startsWith("\\") || tmp.startsWith("/")) //NOI18N
394: tmp = tmp.substring(1);
395: sb.append(PLATFORM_STRING_PREFIX).append(tmp)
396: .append(PATH_SEPARATOR);
397: }
398: } else {
399: final File f = FileUtil.toFile(fo);
400: if (f != null) {
401: sb.append(f.getAbsolutePath()).append(
402: PATH_SEPARATOR);
403: }
404: }
405: } else if (o instanceof URL) {
406: final URL url = (URL) o;
407: try {
408: FileObject fo = URLMapper.findFileObject(url);
409: if (fo != null && home != null
410: && FileUtil.isParentOf(home, fo)) {
411: String tmp = FileUtil.getRelativePath(home, fo);
412: if (tmp != null) {
413: if (tmp.startsWith("\\")
414: || tmp.startsWith("/")) //NOI18N
415: tmp = tmp.substring(1);
416: sb.append(PLATFORM_STRING_PREFIX).append(
417: tmp).append(URL_SEPARATOR);
418: }
419: } else
420: sb.append(url.toString()).append(URL_SEPARATOR);
421: } catch (Exception e) {
422: }
423: }
424: }
425: return sb.toString();
426: }
427:
428: public String getJavadocPath() {
429: return toRelativePaths(javadocs);
430: }
431:
432: public ClassPath getSourceFolders() {
433: return sources;
434: }
435:
436: public void setSourceFolders(final List<FileObject> sources) {
437: this .sources = ClassPathSupport.createClassPath(sources
438: .toArray(new FileObject[sources.size()]));
439: firePropertyChange("sourceFolders", null, null); //NOI18N
440: }
441:
442: public String getSourcePath() {
443: return toRelativePaths(Arrays.asList(sources.getRoots()));
444: }
445:
446: public Map<String, String> getProperties() {
447: return Collections.singletonMap("platform.ant.name", getName()); //NOI18N
448: }
449:
450: public synchronized Specification getSpecification() {
451: if (spec == null) {
452: final HashSet<J2MEProfile> profs = new HashSet<J2MEProfile>();
453: for (int i = 0; i < devices.length; i++) {
454: final J2MEProfile[] profiles = devices[i].getProfiles();
455: for (int j = 0; j < profiles.length; j++)
456: profs.add(profiles[j]);
457: }
458: spec = new Specification(SPECIFICATION_NAME, null, profs
459: .toArray(new Profile[profs.size()]));
460: }
461: return spec;
462: }
463:
464: public boolean isValid() {
465: if (getInstallFolders().size() == 0 || devices == null)
466: return false;
467: for (int i = 0; i < devices.length; i++)
468: if (devices[i].isValid())
469: return true;
470: return false;
471: }
472:
473: public static final class Device {
474:
475: private final String name;
476: private final String description;
477: private final String[] securityDomains;
478: private final J2MEProfile[] profiles;
479: private final Screen screen;
480: private final String[] pathOrder;
481:
482: public Device(String name, String description,
483: String[] securityDomains, J2MEProfile[] profiles,
484: Screen screen) {
485: this .screen = screen;
486: assert name != null;
487: this .name = name;
488: this .description = description == null ? name : description;
489: this .securityDomains = securityDomains;
490: assert profiles != null;
491: this .profiles = profiles;
492:
493: //following algorithm tries to determine if the profile has a unique jar on classpath that makes it realy optional (un-selectable)
494: //and to determine physical path order to keep higher version of API first
495: Set<String> paths[] = new Set[profiles.length];
496: HashMap<String, HashMap<String, SpecificationVersion>> allPaths = new HashMap<String, HashMap<String, SpecificationVersion>>();
497: HashSet<String> doubledPaths = new HashSet<String>();
498: for (int i = 0; i < paths.length; i++) {
499: paths[i] = new HashSet<String>();
500: String s[] = PropertyUtils.tokenizePath(profiles[i]
501: .getClassPath());
502: for (int j = 0; j < s.length; j++) {
503: paths[i].add(s[j]);
504: HashMap<String, SpecificationVersion> apis = allPaths
505: .get(s[j]);
506: if (apis == null) {
507: apis = new HashMap<String, SpecificationVersion>();
508: allPaths.put(s[j], apis);
509: } else {
510: doubledPaths.add(s[j]);
511: }
512: apis.put(profiles[i].getName(), profiles[i]
513: .getVersion());
514: }
515: }
516: for (int i = 0; i < paths.length; i++) {
517: profiles[i].realyOptional = paths[i]
518: .retainAll(doubledPaths);
519: }
520: this .pathOrder = new String[allPaths.size()];
521: for (int i = 0; i < pathOrder.length; i++) {
522: String first = findFirst(allPaths);
523: pathOrder[i] = first;
524: allPaths.remove(first);
525: }
526: }
527:
528: public String sortClasspath(final String classpath) {
529: final HashSet<String> path = new HashSet<String>(Arrays
530: .asList(PropertyUtils.tokenizePath(classpath)));
531: final StringBuffer newPath = new StringBuffer();
532: for (int i = 0; i < pathOrder.length; i++) {
533: if (path.remove(pathOrder[i])) {
534: if (newPath.length() > 0)
535: newPath.append(':');
536: newPath.append(pathOrder[i]);
537: }
538: }
539: for (String str : path) {
540: if (newPath.length() > 0)
541: newPath.append(':');
542: newPath.append(str);
543: }
544: return newPath.toString();
545: }
546:
547: /**
548: * Getter for property name.
549: * @return Value of property name.
550: */
551: public String getName() {
552: return this .name;
553: }
554:
555: public String toString() {
556: return getName();
557: }
558:
559: /**
560: * Getter for property description.
561: * @return Value of property description.
562: */
563: public String getDescription() {
564: return this .description;
565: }
566:
567: /**
568: * Getter for property securitydomains.
569: * @return Value of property securitydomains.
570: */
571: public String[] getSecurityDomains() {
572: return securityDomains == null ? null
573: : (String[]) this .securityDomains.clone();
574: }
575:
576: /**
577: * Getter for property profiles.
578: * @return Value of property profiles.
579: */
580: public J2MEProfile[] getProfiles() {
581: return profiles == null ? null
582: : (J2MEProfile[]) this .profiles.clone();
583: }
584:
585: public Screen getScreen() {
586: return screen;
587: }
588:
589: public boolean isValid() {
590: if (profiles == null)
591: return false;
592: boolean cfg = false, prof = false;
593: for (int i = 0; i < profiles.length; i++) {
594: cfg = cfg
595: || profiles[i].getType().equals(
596: J2MEProfile.TYPE_CONFIGURATION);
597: prof = prof
598: || profiles[i].getType().equals(
599: J2MEProfile.TYPE_PROFILE);
600: }
601: return cfg && prof;
602: }
603:
604: //finds the API that can be ordered as the first of all the given with preference to put CLDC and MIDP at the end
605: private String findFirst(
606: final HashMap<String, HashMap<String, SpecificationVersion>> allPaths) {
607: Map.Entry<String, HashMap<String, SpecificationVersion>> last = null;
608: for (final Map.Entry<String, HashMap<String, SpecificationVersion>> me : allPaths
609: .entrySet()) {
610: final Map<String, SpecificationVersion> apis = me
611: .getValue();
612: if (!apis.containsKey("CLDC")
613: && !apis.containsKey("MIDP")
614: && canBeFirst(apis, allPaths))
615: return me.getKey(); //NOI18N
616: last = me;
617: }
618:
619: for (final Map.Entry<String, HashMap<String, SpecificationVersion>> me : allPaths
620: .entrySet()) {
621: if (canBeFirst(me.getValue(), allPaths))
622: return me.getKey();
623: last = me;
624: }
625: return last.getKey(); //error case - return anything
626: }
627:
628: //tests if given map of APIs can be ordered prior all the other APIs
629: private boolean canBeFirst(
630: final Map<String, SpecificationVersion> map,
631: final HashMap<String, HashMap<String, SpecificationVersion>> allPaths) {
632: for (HashMap<String, SpecificationVersion> svmap : allPaths
633: .values()) {
634: if (!isValidOrder(map, svmap))
635: return false;
636: }
637: return true;
638: }
639:
640: //this method should return false only when there is possible ordering and it is opposite then given arguments
641: //all the other cases return true (equal versions of the same API, cross-dependencies, valid order, no common APIs,...)
642: private boolean isValidOrder(
643: final Map<String, SpecificationVersion> firstAPImap,
644: final HashMap<String, SpecificationVersion> secondAPImap) {
645: final HashSet<String> hs = new HashSet<String>(firstAPImap
646: .keySet());
647: hs.retainAll(secondAPImap.keySet());
648: if (hs.isEmpty())
649: return true;
650: for (final String api : hs) {
651: if (firstAPImap.get(api).compareTo(
652: secondAPImap.get(api)) >= 0)
653: return true;
654: }
655: return false;
656: }
657: }
658:
659: public static final class Screen {
660:
661: private final Integer width;
662: private final Integer height;
663: private final Integer bitDepth;
664: private final Boolean color;
665: private final Boolean touch;
666:
667: public Screen(String width, String height, String bitDepth,
668: String color, String touch) {
669: Object o;
670: try {
671: o = new Integer(width);
672: } catch (NumberFormatException e) {
673: o = null;
674: }
675: this .width = (Integer) o;
676:
677: try {
678: o = new Integer(height);
679: } catch (NumberFormatException e) {
680: o = null;
681: }
682: this .height = (Integer) o;
683:
684: try {
685: o = new Integer(bitDepth);
686: } catch (NumberFormatException e) {
687: o = null;
688: }
689: this .bitDepth = (Integer) o;
690:
691: try {
692: o = new Boolean(color);
693: } catch (NumberFormatException e) {
694: o = null;
695: }
696: this .color = (Boolean) o;
697:
698: try {
699: o = new Boolean(touch);
700: } catch (NumberFormatException e) {
701: o = null;
702: }
703: this .touch = (Boolean) o;
704: }
705:
706: public Integer getBitDepth() {
707: return bitDepth;
708: }
709:
710: public Boolean getColor() {
711: return color;
712: }
713:
714: public Integer getHeight() {
715: return height;
716: }
717:
718: public Boolean getTouch() {
719: return touch;
720: }
721:
722: public Integer getWidth() {
723: return width;
724: }
725:
726: public boolean equals(Object obj) {
727: if (obj instanceof Screen) {
728: Integer width = ((Screen) obj).getWidth();
729: Integer height = ((Screen) obj).getHeight();
730: Integer bitDepth = ((Screen) obj).getBitDepth();
731: Boolean color = ((Screen) obj).getColor();
732: Boolean touch = ((Screen) obj).getTouch();
733: boolean ret = true;
734:
735: ret &= width != null ? width.equals(this .width) : false;
736: ret &= height != null ? height.equals(this .height)
737: : false;
738: ret &= bitDepth != null ? bitDepth
739: .equals(this .bitDepth) : false;
740: ret &= color != null ? color.equals(this .color) : false;
741: ret &= touch != null ? touch.equals(this .touch) : false;
742: return ret;
743: }
744: return false;
745: }
746: }
747:
748: public static final class J2MEProfile extends Profile implements
749: Comparable {
750:
751: public static final String TYPE_CONFIGURATION = "configuration"; //NOI18N
752: public static final String TYPE_PROFILE = "profile"; //NOI18N
753: public static final String TYPE_OPTIONAL = "optional"; //NOI18N
754:
755: private static final MessageFormat DISPLAY_NAME_WITH_VERSION_FORMAT = new MessageFormat(
756: NbBundle
757: .getMessage(J2MEPlatform.class,
758: "FMT_J2MEPlatform_J2MEProfile_DisplayNameWithVersion")); //NOI18N
759:
760: private final String displayName;
761: private final String displayNameWithVersion;
762: private final String type;
763: private final String dependencies;
764: private final String classPath;
765: private final boolean def;
766: boolean realyOptional;
767:
768: public J2MEProfile(String name, String version,
769: String displayName, String type, String dependencies,
770: String classPath, boolean def) {
771: this (name, new SpecificationVersion(version), displayName,
772: type, dependencies, classPath, def);
773: }
774:
775: J2MEProfile(String name, SpecificationVersion version,
776: String displayName, String type, String dependencies,
777: String classPath, boolean def) {
778: super (name, version);
779: assert name != null;
780: assert version != null;
781: this .displayName = displayName == null ? name : displayName;
782: //this is an ugly workaround for IMP-NG profile where the NG is the version number so no other version number should be appended
783: if ("IMP-NG".equalsIgnoreCase(getName()))
784: this .displayNameWithVersion = getDisplayName(); //NOI18N
785: else
786: this .displayNameWithVersion = DISPLAY_NAME_WITH_VERSION_FORMAT
787: .format(
788: new Object[] { getDisplayName(),
789: getVersion().toString() },
790: new StringBuffer(), null).toString();
791: assert type != null;
792: this .type = type;
793: this .dependencies = dependencies != null ? dependencies
794: : ""; //NOI18N
795: this .classPath = classPath == null ? "" : classPath; // NOI18N
796: this .def = def;
797: }
798:
799: public String getDisplayName() {
800: return this .displayName;
801: }
802:
803: public String getDisplayNameWithVersion() {
804: return this .displayNameWithVersion;
805: }
806:
807: public String getType() {
808: return this .type;
809: }
810:
811: public String getDependencies() {
812: return this .dependencies;
813: }
814:
815: public String getClassPath() {
816: assert this .classPath != null;
817: return this .classPath;
818: }
819:
820: public boolean isDefault() {
821: return this .def;
822: }
823:
824: public boolean isRealyOptional() {
825: return this .realyOptional;
826: }
827:
828: public boolean isNameIsJarFileName() {
829: return classPath.equals(PLATFORM_STRING_PREFIX
830: + displayName);
831: }
832:
833: public String toString() {
834: return isNameIsJarFileName()
835: || "IMP-NG".equalsIgnoreCase(getName()) ? getName()
836: : getName() + '-' + getVersion().toString(); //NOI18N
837: }
838:
839: public int compareTo(final Object o) {
840: final Profile p = (Profile) o;
841: final int r = getName().compareTo(p.getName());
842: if (r != 0)
843: return r;
844: if (getVersion() == null)
845: return p.getVersion() == null ? 0 : -1;
846: return p.getVersion() == null ? 1 : getVersion().compareTo(
847: p.getVersion());
848: }
849:
850: }
851:
852: public static FileObject getSubFileObject(final FileObject folder,
853: String name) {
854: if (folder == null || name == null)
855: return null;
856: if (Utilities.isWindows()) {
857: name = name + ".exe"; //NOI18N
858: final FileObject[] fos = folder.getChildren();
859: if (fos != null)
860: for (int a = 0; a < fos.length; a++) {
861: if (name.equalsIgnoreCase(fos[a].getNameExt()))
862: return fos[a];
863: }
864: return null;
865: }
866: return folder.getFileObject(name);
867: }
868:
869: public static FileObject findTool(final String toolName,
870: final Collection<FileObject> installFolders) {
871: assert toolName != null;
872: for (final FileObject root : installFolders) {
873: final FileObject bin = root.getFileObject("bin"); //NOI18N
874: if (bin == null) {
875: continue;
876: }
877: final FileObject tool = getSubFileObject(bin, toolName);
878: if (tool != null) {
879: return tool;
880: }
881: }
882: return null;
883: }
884:
885: public FileObject findTool(final String toolName) {
886: return findTool(toolName, this .getInstallFolders());
887: }
888:
889: public static DataObject createPlatform(final String platformPath)
890: throws IOException {
891: final J2MEPlatform p = new UEIEmulatorConfiguratorImpl(
892: platformPath).getPlatform();
893: return p == null ? null : createPlatform(p);
894: }
895:
896: public static DataObject createPlatform(final J2MEPlatform platform)
897: throws IOException {
898: final String name = platform.getName();
899: final FileObject platformsFolder = Repository
900: .getDefault()
901: .getDefaultFileSystem()
902: .findResource(
903: "Services/Platforms/org-netbeans-api-java-Platform"); //NOI18N
904: if (platformsFolder.getFileObject(name, "xml") != null) //NOI18N
905: return null;
906: return PlatformConvertor.create(platform, DataFolder
907: .findFolder(platformsFolder), name);
908: }
909:
910: public static String computeUniqueName(final String platformName) {
911: final StringBuffer antname = new StringBuffer();
912: for (int a = 0; a < platformName.length(); a++) {
913: final char c = platformName.charAt(a);
914: if (Character.isJavaIdentifierPart(c))
915: antname.append(c);
916: else
917: antname.append('_');
918: }
919:
920: return antname.toString(); // + "@" + Long.toHexString (((long) hashCode.toString ().hashCode ()) & 0xFFFFFFFFl).toUpperCase (); //NOI18N
921: }
922:
923: /**
924: * Setter for property runCmd.
925: * @param runCmd New value of property runCmd.
926: */
927: public void setRunCmd(final String runCmd) {
928: final String old = this .runCmd;
929: this .runCmd = runCmd;
930: firePropertyChange("runCmd", old, runCmd); //NOI18N
931: }
932:
933: /**
934: * Setter for property preverifyCmd.
935: * @param preverifyCmd New value of property preverifyCmd.
936: */
937: public void setPreverifyCmd(final String preverifyCmd) {
938: final String old = this .preverifyCmd;
939: this .preverifyCmd = preverifyCmd;
940: firePropertyChange("preverifyCmd", old, preverifyCmd); //NOI18N
941: }
942:
943: /**
944: * Setter for property debugCmd.
945: * @param debugCmd New value of property debugCmd.
946: */
947: public void setDebugCmd(final String debugCmd) {
948: final String old = this .debugCmd;
949: this .debugCmd = debugCmd;
950: firePropertyChange("debugCmd", old, debugCmd); //NOI18N
951: }
952:
953: }
|