001: /*******************************************************************************
002: * Copyright (c) 2000, 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.pde.internal.core.feature;
011:
012: import java.io.PrintWriter;
013: import java.util.ArrayList;
014: import java.util.List;
015: import java.util.Locale;
016: import java.util.Vector;
017:
018: import org.eclipse.core.runtime.CoreException;
019: import org.eclipse.osgi.service.resolver.BundleDescription;
020: import org.eclipse.osgi.service.resolver.HostSpecification;
021: import org.eclipse.osgi.service.resolver.VersionRange;
022: import org.eclipse.pde.core.IModelChangedEvent;
023: import org.eclipse.pde.core.plugin.IMatchRules;
024: import org.eclipse.pde.core.plugin.IPluginBase;
025: import org.eclipse.pde.core.plugin.IPluginImport;
026: import org.eclipse.pde.core.plugin.IPluginModelBase;
027: import org.eclipse.pde.core.plugin.PluginRegistry;
028: import org.eclipse.pde.internal.core.ifeature.IFeature;
029: import org.eclipse.pde.internal.core.ifeature.IFeatureChild;
030: import org.eclipse.pde.internal.core.ifeature.IFeatureData;
031: import org.eclipse.pde.internal.core.ifeature.IFeatureImport;
032: import org.eclipse.pde.internal.core.ifeature.IFeatureInfo;
033: import org.eclipse.pde.internal.core.ifeature.IFeatureInstallHandler;
034: import org.eclipse.pde.internal.core.ifeature.IFeaturePlugin;
035: import org.eclipse.pde.internal.core.ifeature.IFeatureURL;
036: import org.eclipse.pde.internal.core.plugin.PluginBase;
037: import org.eclipse.pde.internal.core.util.VersionUtil;
038: import org.w3c.dom.Node;
039: import org.w3c.dom.NodeList;
040:
041: public class Feature extends VersionableObject implements IFeature {
042: private static final long serialVersionUID = 1L;
043: final static String INDENT = " "; //$NON-NLS-1$
044: private String fProviderName;
045: private IFeatureURL fUrl;
046: private IFeatureInfo[] fInfos = new IFeatureInfo[3];
047: private Vector fData = new Vector();
048: private Vector fChildren = new Vector();
049: private Vector fPlugins = new Vector();
050: private Vector fImports = new Vector();
051: private String fOs;
052: private String fWs;
053: private String fNl;
054: private String fArch;
055: private String fImageName;
056: private IFeatureInstallHandler fHandler;
057: private boolean fPrimary;
058: private boolean fExclusive;
059: private String fColocationAffinity;
060: private String fApplication;
061: private String fPlugin;
062: private boolean fValid;
063: private String fCopyright;
064:
065: public void addPlugins(IFeaturePlugin[] newPlugins)
066: throws CoreException {
067: ensureModelEditable();
068: for (int i = 0; i < newPlugins.length; i++) {
069: fPlugins.add(newPlugins[i]);
070: ((FeaturePlugin) newPlugins[i]).setInTheModel(true);
071: }
072: fireStructureChanged(newPlugins, IModelChangedEvent.INSERT);
073: }
074:
075: public void addData(IFeatureData[] newData) throws CoreException {
076: ensureModelEditable();
077: for (int i = 0; i < newData.length; i++) {
078: fData.add(newData[i]);
079: ((FeatureData) newData[i]).setInTheModel(true);
080: }
081: fireStructureChanged(newData, IModelChangedEvent.INSERT);
082: }
083:
084: public void addIncludedFeatures(IFeatureChild[] features)
085: throws CoreException {
086: ensureModelEditable();
087: for (int i = 0; i < features.length; i++) {
088: fChildren.add(features[i]);
089: ((FeatureChild) features[i]).setInTheModel(true);
090: }
091: fireStructureChanged(features, IModelChangedEvent.INSERT);
092: }
093:
094: public void addImports(IFeatureImport[] iimports)
095: throws CoreException {
096: ensureModelEditable();
097: for (int i = 0; i < iimports.length; i++) {
098: fImports.add(iimports[i]);
099: ((FeatureImport) iimports[i]).setInTheModel(true);
100: }
101: fireStructureChanged(iimports, IModelChangedEvent.INSERT);
102: }
103:
104: public IFeaturePlugin[] getPlugins() {
105: IFeaturePlugin[] result = new IFeaturePlugin[fPlugins.size()];
106: fPlugins.copyInto(result);
107: return result;
108: }
109:
110: public IFeatureData[] getData() {
111: IFeatureData[] result = new IFeatureData[fData.size()];
112: fData.copyInto(result);
113: return result;
114: }
115:
116: public IFeatureChild[] getIncludedFeatures() {
117: IFeatureChild[] result = new IFeatureChild[fChildren.size()];
118: fChildren.copyInto(result);
119: return result;
120: }
121:
122: public IFeatureImport[] getImports() {
123: IFeatureImport[] result = new IFeatureImport[fImports.size()];
124: fImports.copyInto(result);
125: return result;
126: }
127:
128: public String getProviderName() {
129: return fProviderName;
130: }
131:
132: public String getPlugin() {
133: return fPlugin;
134: }
135:
136: public IPluginModelBase getReferencedModel(IFeaturePlugin reference) {
137: IPluginModelBase model = PluginRegistry.findModel(reference
138: .getId());
139: return (model != null && model.isEnabled()) ? model : null;
140: }
141:
142: public IFeatureURL getURL() {
143: return fUrl;
144: }
145:
146: public IFeatureInstallHandler getInstallHandler() {
147: return fHandler;
148: }
149:
150: public IFeatureInfo getFeatureInfo(int index) {
151: return fInfos[index];
152: }
153:
154: public boolean isPrimary() {
155: return fPrimary;
156: }
157:
158: public boolean isExclusive() {
159: return fExclusive;
160: }
161:
162: protected void parse(Node node) {
163: super .parse(node);
164: fProviderName = getNodeAttribute(node, "provider-name"); //$NON-NLS-1$
165: fPlugin = getNodeAttribute(node, "plugin"); //$NON-NLS-1$
166: fOs = getNodeAttribute(node, "os"); //$NON-NLS-1$
167: fWs = getNodeAttribute(node, "ws"); //$NON-NLS-1$
168: fNl = getNodeAttribute(node, "nl"); //$NON-NLS-1$
169: fArch = getNodeAttribute(node, "arch"); //$NON-NLS-1$
170: fImageName = getNodeAttribute(node, "image"); //$NON-NLS-1$
171: fColocationAffinity = getNodeAttribute(node,
172: "colocation-affinity"); //$NON-NLS-1$
173: fApplication = getNodeAttribute(node, "application"); //$NON-NLS-1$
174: fPrimary = getBooleanAttribute(node, "primary"); //$NON-NLS-1$
175: fExclusive = getBooleanAttribute(node, "exclusive"); //$NON-NLS-1$
176: NodeList children = node.getChildNodes();
177: fValid = true;
178:
179: for (int i = 0; i < children.getLength(); i++) {
180: Node child = children.item(i);
181: if (child.getNodeType() == Node.ELEMENT_NODE) {
182: String tag = child.getNodeName().toLowerCase(
183: Locale.ENGLISH);
184: if (tag.equals("description")) { //$NON-NLS-1$
185: IFeatureInfo info = getModel().getFactory()
186: .createInfo(IFeature.INFO_DESCRIPTION);
187: ((FeatureInfo) info).setInTheModel(true);
188: ((FeatureInfo) info).parse(child);
189: fInfos[IFeature.INFO_DESCRIPTION] = info;
190: } else if (tag.equals("license")) { //$NON-NLS-1$
191: IFeatureInfo info = getModel().getFactory()
192: .createInfo(IFeature.INFO_LICENSE);
193: ((FeatureInfo) info).setInTheModel(true);
194: ((FeatureInfo) info).parse(child);
195: fInfos[IFeature.INFO_LICENSE] = info;
196: } else if (tag.equals("copyright")) { //$NON-NLS-1$
197: IFeatureInfo info = getModel().getFactory()
198: .createInfo(IFeature.INFO_COPYRIGHT);
199: ((FeatureInfo) info).setInTheModel(true);
200: ((FeatureInfo) info).parse(child);
201: fInfos[IFeature.INFO_COPYRIGHT] = info;
202: } else if (tag.equals("url")) { //$NON-NLS-1$
203: if (fUrl == null) {
204: fUrl = getModel().getFactory().createURL();
205: ((FeatureURL) fUrl).setInTheModel(true);
206: ((FeatureURL) fUrl).parse(child);
207: }
208: } else if (tag.equals("requires")) { //$NON-NLS-1$
209: parseRequires(child);
210: } else if (tag.equals("install-handler")) { //$NON-NLS-1$
211: IFeatureInstallHandler handler = getModel()
212: .getFactory().createInstallHandler();
213: ((FeatureInstallHandler) handler).parse(child);
214: ((FeatureInstallHandler) handler)
215: .setInTheModel(true);
216: this .fHandler = handler;
217: } else if (tag.equals("plugin")) { //$NON-NLS-1$
218: IFeaturePlugin plugin = getModel().getFactory()
219: .createPlugin();
220: ((FeaturePlugin) plugin).parse(child);
221: ((FeaturePlugin) plugin).setInTheModel(true);
222: fPlugins.add(plugin);
223: } else if (tag.equals("data")) { //$NON-NLS-1$
224: IFeatureData newData = getModel().getFactory()
225: .createData();
226: ((FeatureData) newData).parse(child);
227: ((FeatureData) newData).setInTheModel(true);
228: fData.add(newData);
229: } else if (tag.equals("includes")) { //$NON-NLS-1$
230: IFeatureChild newChild = getModel().getFactory()
231: .createChild();
232: ((FeatureChild) newChild).parse(child);
233: ((FeatureChild) newChild).setInTheModel(true);
234: this .fChildren.add(newChild);
235: }
236: }
237: }
238: fValid = hasRequiredAttributes();
239: }
240:
241: private void parseRequires(Node node) {
242: NodeList children = node.getChildNodes();
243: for (int i = 0; i < children.getLength(); i++) {
244: Node child = children.item(i);
245: if (child.getNodeType() == Node.ELEMENT_NODE) {
246: if (child.getNodeName().equalsIgnoreCase("import")) { //$NON-NLS-1$
247: IFeatureImport iimport = getModel().getFactory()
248: .createImport();
249: ((FeatureImport) iimport).parse(child);
250: ((FeatureImport) iimport).setInTheModel(true);
251: fImports.add(iimport);
252: }
253: }
254: }
255: }
256:
257: public void computeImports() throws CoreException {
258: // some existing imports may valid and can be preserved
259: Vector preservedImports = new Vector(fImports.size());
260: // new imports
261: ArrayList newImports = new ArrayList();
262: for (int i = 0; i < fPlugins.size(); i++) {
263: IFeaturePlugin fp = (IFeaturePlugin) fPlugins.get(i);
264: IPluginModelBase model = PluginRegistry.findModel(fp
265: .getId());
266: if (model != null) {
267: addPluginImports(preservedImports, newImports, model
268: .getPluginBase());
269: if (model.isFragmentModel()) {
270: BundleDescription desc = model
271: .getBundleDescription();
272: if (desc == null)
273: continue;
274: HostSpecification hostSpec = desc.getHost();
275: String id = hostSpec.getName();
276: String version = null;
277: int match = IMatchRules.NONE;
278: VersionRange versionRange = hostSpec
279: .getVersionRange();
280: if (!(versionRange == null || VersionRange.emptyRange
281: .equals(versionRange))) {
282: version = versionRange.getMinimum() != null ? versionRange
283: .getMinimum().toString()
284: : null;
285: match = PluginBase.getMatchRule(versionRange);
286: }
287: addNewDependency(id, version, match,
288: preservedImports, newImports);
289: }
290: }
291: }
292: // preserve imports of features
293: for (int i = 0; i < fImports.size(); i++) {
294: IFeatureImport iimport = (IFeatureImport) fImports.get(i);
295: if (iimport.getType() == IFeatureImport.FEATURE)
296: preservedImports.add(iimport);
297: }
298: // removed = old - preserved
299: Vector removedImports = ((Vector) fImports.clone());
300: removedImports.removeAll(preservedImports);
301: // perform remove
302: fImports = preservedImports;
303: if (removedImports.size() > 0) {
304: fireStructureChanged(
305: (IFeatureImport[]) removedImports
306: .toArray(new IFeatureImport[removedImports
307: .size()]),
308: IModelChangedEvent.REMOVE);
309: }
310: // perform add
311: if (newImports.size() > 0) {
312: fImports.addAll(newImports);
313: fireStructureChanged((IFeatureImport[]) newImports
314: .toArray(new IFeatureImport[newImports.size()]),
315: IModelChangedEvent.INSERT);
316: }
317: }
318:
319: /**
320: * Creates IFeatureImports based on IPluginImports. Ensures no duplicates in
321: * preservedImports + newImports
322: *
323: * @param preservedImports
324: * out for valid existing imports
325: * @param newImports
326: * out for new imports
327: * @param plugin
328: * @throws CoreException
329: */
330: private void addPluginImports(List preservedImports,
331: List newImports, IPluginBase plugin) throws CoreException {
332: IPluginImport[] pluginImports = plugin.getImports();
333: for (int i = 0; i < pluginImports.length; i++) {
334: IPluginImport pluginImport = pluginImports[i];
335: if (pluginImport.isOptional()) {
336: continue;
337: }
338: String id = pluginImport.getId();
339: String version = pluginImport.getVersion();
340: int match = pluginImport.getMatch();
341: addNewDependency(id, version, match, preservedImports,
342: newImports);
343: }
344: }
345:
346: private void addNewDependency(String id, String version, int match,
347: List preservedImports, List newImports)
348: throws CoreException {
349: if (findFeaturePlugin(id, version, match) != null) {
350: // don't add imports to local plug-ins
351: return;
352: }
353: if (findImport(preservedImports, id, version, match) != null) {
354: // already seen
355: return;
356: }
357: if (findImport(newImports, id, version, match) != null) {
358: // already seen
359: return;
360: }
361: IFeatureImport iimport = findImport(fImports, id, version,
362: match);
363: if (iimport != null) {
364: // import still valid
365: preservedImports.add(iimport);
366: return;
367: }
368: // a new one is needed
369: iimport = getModel().getFactory().createImport();
370: iimport.setId(id);
371: iimport.setVersion(version);
372: iimport.setMatch(match);
373: ((FeatureImport) iimport).setInTheModel(true);
374: newImports.add(iimport);
375: }
376:
377: /**
378: * Finds a given import in the list
379: * @param imports list of imports
380: * @param id
381: * @param version
382: * @param match
383: * @return IFeatureImport or null
384: */
385: private IFeatureImport findImport(List imports, String id,
386: String version, int match) {
387: for (int i = 0; i < imports.size(); i++) {
388: IFeatureImport iimport = (IFeatureImport) imports.get(i);
389: if (iimport.getId().equals(id)) {
390: if (version == null)
391: return iimport;
392: if (version.equals(iimport.getVersion())
393: && match == iimport.getMatch())
394: return iimport;
395: }
396: }
397: return null;
398: }
399:
400: private IFeaturePlugin findFeaturePlugin(String id, String version,
401: int match) {
402:
403: for (int i = 0; i < fPlugins.size(); i++) {
404: IFeaturePlugin fp = (IFeaturePlugin) fPlugins.get(i);
405: String pid = fp.getId();
406: String pversion = fp.getVersion();
407: if (VersionUtil.compare(pid, pversion, id, version, match))
408: return fp;
409: }
410: return null;
411: }
412:
413: public void removePlugins(IFeaturePlugin[] removed)
414: throws CoreException {
415: ensureModelEditable();
416: for (int i = 0; i < removed.length; i++) {
417: fPlugins.remove(removed[i]);
418: ((FeaturePlugin) removed[i]).setInTheModel(false);
419: }
420: fireStructureChanged(removed, IModelChangedEvent.REMOVE);
421: }
422:
423: public void removeData(IFeatureData[] removed) throws CoreException {
424: ensureModelEditable();
425: for (int i = 0; i < removed.length; i++) {
426: fData.remove(removed[i]);
427: ((FeatureData) removed[i]).setInTheModel(false);
428: }
429: fireStructureChanged(removed, IModelChangedEvent.REMOVE);
430: }
431:
432: public void removeIncludedFeatures(IFeatureChild[] features)
433: throws CoreException {
434: ensureModelEditable();
435: for (int i = 0; i < features.length; i++) {
436: fChildren.remove(features[i]);
437: ((FeatureChild) features[i]).setInTheModel(false);
438: }
439: fireStructureChanged(features, IModelChangedEvent.REMOVE);
440: }
441:
442: public void removeImports(IFeatureImport[] iimports)
443: throws CoreException {
444: ensureModelEditable();
445: for (int i = 0; i < iimports.length; i++) {
446: fImports.remove(iimports[i]);
447: ((FeatureImport) iimports[i]).setInTheModel(false);
448: }
449: fireStructureChanged(iimports, IModelChangedEvent.REMOVE);
450: }
451:
452: public String getOS() {
453: return fOs;
454: }
455:
456: public String getWS() {
457: return fWs;
458: }
459:
460: public String getNL() {
461: return fNl;
462: }
463:
464: public String getArch() {
465: return fArch;
466: }
467:
468: public String getColocationAffinity() {
469: return fColocationAffinity;
470: }
471:
472: public String getApplication() {
473: return fApplication;
474: }
475:
476: public void setOS(String os) throws CoreException {
477: ensureModelEditable();
478: Object oldValue = this .fOs;
479: this .fOs = os;
480: firePropertyChanged(P_OS, oldValue, os);
481: }
482:
483: public void setWS(String ws) throws CoreException {
484: ensureModelEditable();
485: Object oldValue = this .fWs;
486: this .fWs = ws;
487: firePropertyChanged(P_WS, oldValue, ws);
488: }
489:
490: public void setNL(String nl) throws CoreException {
491: ensureModelEditable();
492: Object oldValue = this .fNl;
493: this .fNl = nl;
494: firePropertyChanged(P_NL, oldValue, nl);
495: }
496:
497: public void setArch(String arch) throws CoreException {
498: ensureModelEditable();
499: Object oldValue = this .fArch;
500: this .fArch = arch;
501: firePropertyChanged(P_ARCH, oldValue, arch);
502: }
503:
504: public void setPrimary(boolean newValue) throws CoreException {
505: if (this .fPrimary == newValue)
506: return;
507: ensureModelEditable();
508: Boolean oldValue = this .fPrimary ? Boolean.TRUE : Boolean.FALSE;
509: this .fPrimary = newValue;
510: firePropertyChanged(P_PRIMARY, oldValue,
511: newValue ? Boolean.TRUE : Boolean.FALSE);
512: }
513:
514: public void setExclusive(boolean newValue) throws CoreException {
515: if (this .fExclusive == newValue)
516: return;
517: ensureModelEditable();
518: Boolean oldValue = this .fExclusive ? Boolean.TRUE
519: : Boolean.FALSE;
520: this .fExclusive = newValue;
521: firePropertyChanged(P_EXCLUSIVE, oldValue,
522: newValue ? Boolean.TRUE : Boolean.FALSE);
523: }
524:
525: public void setColocationAffinity(String newValue)
526: throws CoreException {
527: ensureModelEditable();
528: Object oldValue = this .fColocationAffinity;
529: this .fColocationAffinity = newValue;
530: firePropertyChanged(P_COLLOCATION_AFFINITY, oldValue, newValue);
531: }
532:
533: public void setApplication(String newValue) throws CoreException {
534: ensureModelEditable();
535: Object oldValue = this .fApplication;
536: this .fApplication = newValue;
537: firePropertyChanged(P_APPLICATION, oldValue, newValue);
538: }
539:
540: public void setProviderName(String providerName)
541: throws CoreException {
542: ensureModelEditable();
543: Object oldValue = this .fProviderName;
544: this .fProviderName = providerName;
545: firePropertyChanged(P_PROVIDER, oldValue, providerName);
546: }
547:
548: public void setPlugin(String plugin) throws CoreException {
549: ensureModelEditable();
550: Object oldValue = this .fPlugin;
551: this .fPlugin = plugin;
552: firePropertyChanged(P_PLUGIN, oldValue, plugin);
553: }
554:
555: public void setURL(IFeatureURL url) throws CoreException {
556: ensureModelEditable();
557: Object oldValue = this .fUrl;
558: if (this .fUrl != null) {
559: ((FeatureURL) this .fUrl).setInTheModel(false);
560: }
561: this .fUrl = url;
562: firePropertyChanged(P_URL, oldValue, url);
563: }
564:
565: public void setInstallHandler(IFeatureInstallHandler handler)
566: throws CoreException {
567: ensureModelEditable();
568: Object oldValue = this .fHandler;
569: if (this .fHandler != null) {
570: ((FeatureInstallHandler) this .fHandler)
571: .setInTheModel(false);
572: }
573: this .fHandler = handler;
574: firePropertyChanged(P_INSTALL_HANDLER, oldValue, handler);
575: }
576:
577: public void setFeatureInfo(IFeatureInfo info, int index)
578: throws CoreException {
579: ensureModelEditable();
580: Object oldValue = fInfos[index];
581: if (oldValue != null) {
582: ((FeatureInfo) oldValue).setInTheModel(true);
583: }
584: fInfos[index] = info;
585: String property;
586: switch (index) {
587: case INFO_DESCRIPTION:
588: property = P_DESCRIPTION;
589: break;
590: case INFO_LICENSE:
591: property = P_LICENSE;
592: break;
593: case INFO_COPYRIGHT:
594: property = P_COPYRIGHT;
595: break;
596: default:
597: return;
598: }
599: firePropertyChanged(property, oldValue, info);
600: }
601:
602: /**
603: * Sets the imageName.
604: *
605: * @param imageName
606: * The imageName to set
607: */
608: public void setImageName(String imageName) throws CoreException {
609: ensureModelEditable();
610: Object oldValue = this .fImageName;
611: this .fImageName = imageName;
612: firePropertyChanged(P_IMAGE, oldValue, imageName);
613: }
614:
615: public void restoreProperty(String name, Object oldValue,
616: Object newValue) throws CoreException {
617: if (name.equals(P_OS)) {
618: setOS((String) newValue);
619: } else if (name.equals(P_WS)) {
620: setWS((String) newValue);
621: } else if (name.equals(P_NL)) {
622: setNL((String) newValue);
623: } else if (name.equals(P_ARCH)) {
624: setArch((String) newValue);
625: } else if (name.equals(P_COLLOCATION_AFFINITY)) {
626: setColocationAffinity((String) newValue);
627: } else if (name.equals(P_APPLICATION)) {
628: setApplication((String) newValue);
629: } else if (name.equals(P_PRIMARY)) {
630: setPrimary(newValue != null ? ((Boolean) newValue)
631: .booleanValue() : false);
632: } else if (name.equals(P_EXCLUSIVE)) {
633: setExclusive(newValue != null ? ((Boolean) newValue)
634: .booleanValue() : false);
635: } else if (name.equals(P_PROVIDER)) {
636: setProviderName((String) newValue);
637: } else if (name.equals(P_PLUGIN)) {
638: setPlugin((String) newValue);
639: } else if (name.equals(P_URL)) {
640: setURL((IFeatureURL) newValue);
641: } else if (name.equals(P_INSTALL_HANDLER)) {
642: setInstallHandler((IFeatureInstallHandler) newValue);
643: } else if (name.equals(P_DESCRIPTION)) {
644: setFeatureInfo((IFeatureInfo) newValue, INFO_DESCRIPTION);
645: } else if (name.equals(P_LICENSE)) {
646: setFeatureInfo((IFeatureInfo) newValue, INFO_LICENSE);
647: } else if (name.equals(P_COPYRIGHT)) {
648: setFeatureInfo((IFeatureInfo) newValue, INFO_COPYRIGHT);
649: } else if (name.equals(P_IMAGE)) {
650: setImageName((String) newValue);
651: } else
652: super .restoreProperty(name, oldValue, newValue);
653: }
654:
655: public void reset() {
656: super .reset();
657: fData.clear();
658: fPlugins.clear();
659: fImports.clear();
660: fChildren.clear();
661: fUrl = null;
662: fProviderName = null;
663: fPlugin = null;
664: fOs = null;
665: fWs = null;
666: fNl = null;
667: fArch = null;
668: fInfos[0] = null;
669: fInfos[1] = null;
670: fInfos[2] = null;
671: fPrimary = false;
672: fExclusive = false;
673: fColocationAffinity = null;
674: fApplication = null;
675: fValid = false;
676: }
677:
678: public boolean isValid() {
679: return fValid;
680: }
681:
682: private boolean hasRequiredAttributes() {
683: // Verify that all the required attributes are
684: // defined.
685: if (id == null)
686: return false;
687: if (version == null)
688: return false;
689:
690: for (int i = 0; i < fChildren.size(); i++) {
691: IFeatureChild child = (IFeatureChild) fChildren
692: .elementAt(i);
693: if (child.getId() == null || child.getVersion() == null)
694: return false;
695: }
696: for (int i = 0; i < fPlugins.size(); i++) {
697: IFeaturePlugin plugin = (IFeaturePlugin) fPlugins
698: .elementAt(i);
699: if (plugin.getId() == null || plugin.getVersion() == null)
700: return false;
701:
702: }
703: for (int i = 0; i < fData.size(); i++) {
704: IFeatureData entry = (IFeatureData) fData.elementAt(i);
705: if (entry.getId() == null)
706: return false;
707: }
708: for (int i = 0; i < fImports.size(); i++) {
709: IFeatureImport iimport = (IFeatureImport) fImports
710: .elementAt(i);
711: if (iimport.getId() == null)
712: return false;
713: }
714: return true;
715: }
716:
717: public void write(String indent, PrintWriter writer) {
718: if (fCopyright != null) {
719: writer.println("<!--" + fCopyright + "-->"); //$NON-NLS-1$ //$NON-NLS-2$
720: }
721: writer.print(indent + "<feature"); //$NON-NLS-1$
722: String indent2 = indent + INDENT;
723: String indenta = indent + INDENT + INDENT;
724: writeIfDefined(indenta, writer, "id", getId()); //$NON-NLS-1$
725: writeIfDefined(indenta, writer,
726: "label", getWritableString(getLabel())); //$NON-NLS-1$
727: writeIfDefined(indenta, writer, "version", getVersion()); //$NON-NLS-1$
728: writeIfDefined(indenta, writer, "provider-name", //$NON-NLS-1$
729: getWritableString(fProviderName));
730: writeIfDefined(indenta, writer, "plugin", //$NON-NLS-1$
731: getPlugin());
732: writeIfDefined(indenta, writer, "os", fOs); //$NON-NLS-1$
733: writeIfDefined(indenta, writer, "ws", fWs); //$NON-NLS-1$
734: writeIfDefined(indenta, writer, "nl", fNl); //$NON-NLS-1$
735: writeIfDefined(indenta, writer, "arch", fArch); //$NON-NLS-1$
736: if (fImageName != null)
737: writeIfDefined(indenta, writer,
738: "image", getWritableString(fImageName)); //$NON-NLS-1$
739: if (isPrimary()) {
740: writer.println();
741: writer.print(indenta + "primary=\"true\""); //$NON-NLS-1$
742: }
743: if (isExclusive()) {
744: writer.println();
745: writer.print(indenta + "exclusive=\"true\""); //$NON-NLS-1$
746: }
747: writeIfDefined(indenta, writer,
748: "colocation-affinity", fColocationAffinity); //$NON-NLS-1$
749: writeIfDefined(indenta, writer, "application", fApplication); //$NON-NLS-1$
750:
751: writer.println(">"); //$NON-NLS-1$
752: if (fHandler != null) {
753: fHandler.write(indent2, writer);
754: }
755:
756: for (int i = 0; i < 3; i++) {
757: IFeatureInfo info = fInfos[i];
758: if (info != null && !info.isEmpty())
759: info.write(indent2, writer);
760: }
761:
762: if (fUrl != null) {
763: fUrl.write(indent2, writer);
764: }
765: for (int i = 0; i < fChildren.size(); i++) {
766: IFeatureChild child = (IFeatureChild) fChildren
767: .elementAt(i);
768: writer.println();
769: child.write(indent2, writer);
770: }
771: if (fImports.size() > 0) {
772: writer.println();
773: writer.println(indent2 + "<requires>"); //$NON-NLS-1$
774: for (int i = 0; i < fImports.size(); i++) {
775: IFeatureImport iimport = (IFeatureImport) fImports
776: .get(i);
777: iimport.write(indenta, writer);
778: }
779: writer.println(indent2 + "</requires>"); //$NON-NLS-1$
780: }
781: for (int i = 0; i < fPlugins.size(); i++) {
782: IFeaturePlugin plugin = (IFeaturePlugin) fPlugins
783: .elementAt(i);
784: writer.println();
785: plugin.write(indent2, writer);
786: }
787: for (int i = 0; i < fData.size(); i++) {
788: IFeatureData entry = (IFeatureData) fData.elementAt(i);
789: writer.println();
790: entry.write(indent2, writer);
791: }
792: writer.println();
793: writer.println(indent + "</feature>"); //$NON-NLS-1$
794: }
795:
796: private void writeIfDefined(String indent, PrintWriter writer,
797: String attName, String attValue) {
798: if (attValue == null || attValue.trim().length() == 0)
799: return;
800: writer.println();
801: writer.print(indent + attName + "=\"" + attValue + "\""); //$NON-NLS-1$ //$NON-NLS-2$
802: }
803:
804: /**
805: * Gets the imageName.
806: *
807: * @return Returns a String
808: */
809: public String getImageName() {
810: return fImageName;
811: }
812:
813: public String getCopyright() {
814: return fCopyright;
815: }
816:
817: public void setCopyright(String copyright) {
818: fCopyright = copyright;
819: }
820: }
|