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-2007 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: /*
043: * UMLProject.java
044: *
045: * Created on February 13, 2004, 4:06 PM
046: */
047:
048: package org.netbeans.modules.uml.project;
049:
050: import java.beans.PropertyChangeEvent;
051: import java.beans.PropertyChangeListener;
052: import java.beans.PropertyChangeSupport;
053: import java.io.File;
054: import java.io.IOException;
055: import javax.swing.Icon;
056: import javax.swing.ImageIcon;
057: import javax.swing.SwingUtilities;
058: import org.netbeans.api.project.FileOwnerQuery;
059: import org.netbeans.api.project.Project;
060: import org.netbeans.api.project.ProjectInformation;
061: import org.netbeans.api.project.ProjectManager;
062: import org.netbeans.api.project.ant.AntArtifact;
063: import org.netbeans.modules.uml.core.reverseengineering.reintegration.ReverseEngineerTask;
064: import org.netbeans.spi.java.project.support.ui.BrokenReferencesSupport;
065: import org.netbeans.spi.project.AuxiliaryConfiguration;
066: import org.netbeans.spi.project.SubprojectProvider;
067: import org.netbeans.spi.project.ant.AntArtifactProvider;
068: import org.netbeans.spi.project.support.ant.AntProjectEvent;
069: import org.netbeans.spi.project.support.ant.AntProjectHelper;
070: import org.netbeans.spi.project.support.ant.AntProjectListener;
071: import org.netbeans.spi.project.support.ant.EditableProperties;
072: import org.netbeans.spi.project.support.ant.GeneratedFilesHelper;
073: import org.netbeans.spi.project.support.ant.PropertyEvaluator;
074: import org.netbeans.spi.project.support.ant.PropertyUtils;
075: import org.netbeans.spi.project.support.ant.ReferenceHelper;
076: import org.netbeans.spi.project.ui.PrivilegedTemplates;
077: import org.netbeans.spi.project.ui.ProjectOpenedHook;
078: import org.netbeans.spi.project.ui.RecommendedTemplates;
079: import org.openide.ErrorManager;
080: import org.openide.filesystems.FileObject;
081: import org.openide.filesystems.FileUtil;
082: import org.openide.util.Lookup;
083: import org.openide.util.Mutex;
084: import org.openide.util.RequestProcessor;
085: import org.openide.util.Utilities;
086: import org.openide.util.lookup.Lookups;
087: import org.w3c.dom.Element;
088: import org.w3c.dom.Node;
089: import org.w3c.dom.NodeList;
090: import org.w3c.dom.Text;
091: import org.netbeans.modules.uml.core.metamodel.structure.IProject;
092: import org.netbeans.modules.uml.core.reverseengineering.reframework.parsingframework.ILanguageManager;
093: import org.netbeans.modules.uml.core.support.umlsupport.IStrings;
094: import org.netbeans.modules.uml.core.support.umlsupport.Strings;
095: import org.netbeans.modules.uml.project.ui.customizer.CustomizerProviderImpl;
096: import org.netbeans.modules.uml.project.ui.customizer.UMLProjectProperties;
097: import org.netbeans.modules.uml.project.ui.nodes.UMLPhysicalViewProvider;
098: import org.netbeans.modules.uml.project.ui.nodes.ModelRootNodeCookie;
099: import org.netbeans.modules.uml.project.ui.customizer.UMLImportsUiSupport;
100: import org.netbeans.modules.uml.resources.images.ImageUtil;
101: import org.netbeans.modules.uml.util.ITaskFinishListener;
102: import org.openide.loaders.DataObject;
103: import org.openide.windows.TopComponent;
104: import org.openide.windows.WindowManager;
105:
106: /**
107: *
108: * @author Trey Spiva
109: */
110: public class UMLProject implements Project, AntProjectListener {
111: private static final Icon PROJECT_ICON = ImageUtil.instance()
112: .getIcon("uml-project.png"); // NOI18N
113:
114: private final Lookup mLookup;
115: private final UMLProjectHelper mHelper;
116: private final ReferenceHelper mRefHelper;
117: private final GeneratedFilesHelper mGenFilesHelper;
118: private final PropertyEvaluator mEval;
119: private final UMLImportsUiSupport mImportSupport;
120:
121: // TODO is this bad practice?
122: UMLProjectProperties uiProperties;
123:
124: public static final int PROJECT_MODE_ANALYSIS = 0;
125: public static final int PROJECT_MODE_DESIGN = 1;
126: public static final int PROJECT_MODE_IMPL = 2;
127:
128: public static final String PROJECT_MODE_ANALYSIS_STR = "Analysis"; // NOI18N
129: public static final String PROJECT_MODE_DESIGN_STR = "Design"; // NOI18N
130: public static final String PROJECT_MODE_IMPL_STR = "Implementation"; // NOI18N
131:
132: public static final String PROJECT_MODE_DEFAULT_STR = PROJECT_MODE_ANALYSIS_STR;
133:
134: public static final int PROJECT_LANG_JAVA = 0;
135: public static final String PROJECT_LANG_JAVA_STR = "Java"; // NOI18N
136: /* NB60TBD
137: public static HashMap<String,MDRChangeListener> listenerMap =
138: new HashMap<String,MDRChangeListener>();
139: */
140: /**
141: * I am attempting to define an AntArtifact type so that we can
142: *leverage all of the AntHelper and ReferenceHelper features when
143: *tracking references across UMLProjects.
144: *This is a bit of a hack because, as of yet, there is no need for a true
145: *ant artifact. But the alternative is to reinvent the wheel in terms of
146: *managing references, and that is unappealing when the Ant Project Support
147: *has already done it.
148: * @see org.netbeans.api.project.ant.AntArtifact
149: */
150: public static final String ARTIFACT_TYPE_UML_PROJ = "umlproj"; // NOI18N
151:
152: /**
153: * This vector holds all Classes and Interfaces in the UML
154: * Project(IProject)
155: *
156: */
157: // public static Vector<String> clazzNames = new Vector<String>();
158: private UMLProjectMetadataListener mListener = null;
159:
160: private DataObject obj;
161:
162: /** Creates a new instance of UMLProject */
163: public UMLProject(AntProjectHelper helper) {
164: mHelper = new UMLProjectHelper(helper, this );
165:
166: mEval = createEvaluator();
167: mImportSupport = new UMLImportsUiSupport(this );
168: AuxiliaryConfiguration aux = helper
169: .createAuxiliaryConfiguration();
170: mRefHelper = new ReferenceHelper(helper, aux, mEval);
171: mGenFilesHelper = new GeneratedFilesHelper(helper);
172:
173: mLookup = createLookup(aux);
174: helper.addAntProjectListener(this );
175:
176: mListener = new UMLProjectMetadataListener(this );
177: // mEval.addPropertyChangeListener(
178: // WeakListeners.propertyChange(mListener, mEval));
179: //
180: // mHelper.getAntProjectHelper().addAntProjectListener(
181: // (AntProjectListener)WeakListeners.create(
182: // AntProjectListener.class, mListener,mHelper));
183: mEval.addPropertyChangeListener(mListener);
184: mHelper.getAntProjectHelper().addAntProjectListener(mListener);
185: }
186:
187: public Lookup getLookup() {
188: return mLookup;
189: }
190:
191: private PropertyEvaluator createEvaluator() {
192: return mHelper.getStandardPropertyEvaluator();
193: }
194:
195: public PropertyEvaluator evaluator() {
196: return mEval;
197: }
198:
199: public void removeUMLProjectMetaListener() {
200: evaluator().removePropertyChangeListener(mListener);
201: mHelper.getAntProjectHelper().removeAntProjectListener(
202: mListener);
203: }
204:
205: public ReferenceHelper getReferenceHelper() {
206: return mRefHelper;
207: }
208:
209: public UMLProjectProperties getUMLProjectProperties() {
210: return uiProperties;
211: }
212:
213: public void setUMLProjectProperties(UMLProjectProperties props) {
214: uiProperties = props;
215: }
216:
217: // TODO - what is the best lookup criteria for a client code to call
218: // to determine if target is a uml project?
219: protected Lookup createLookup(AuxiliaryConfiguration aux) {
220: SubprojectProvider spp = mRefHelper.createSubprojectProvider();
221:
222: Object[] lookupObjs = {
223: new Info(),
224: aux,
225: mHelper.createCacheDirectoryProvider(),
226: spp,
227: new UMLActionProvider(this , mHelper),
228: new UMLPhysicalViewProvider(this , mHelper, mEval, spp,
229: mImportSupport, mRefHelper),
230: new CustomizerProviderImpl(this , mHelper, mEval,
231: mRefHelper),
232: //new ProjectXMLSavedHook(),
233: new ProjectOpenedHookImpl(),
234: new RecommendedTemplatesImpl(),
235: mHelper,
236: // MCF we can't add the IProject at this point because it is not
237: // properly initialized yet. And it messes up the first save
238: // operation. So we opt to omit it from lookupObjs. It will still
239: // be easily accessible via the mHelper.getProject
240: //
241: // mHelper.getProject(),
242: //
243: new AntProjectHelperProvider(),
244: new AntArtifactProviderImpl(),
245: new AssociatedSourceProvider(this , mHelper, mEval) };
246: return Lookups.fixed(lookupObjs);
247: }
248:
249: public FileObject getProjectDirectory() {
250: return mHelper.getProjectDirectory();
251: }
252:
253: /** Return configured project name. */
254: public String getName() {
255: return (String) ProjectManager.mutex().readAccess(
256: new Mutex.Action() {
257: public Object run() {
258: Element data = mHelper
259: .getPrimaryConfigurationData(true);
260:
261: // XXX replace by XMLUtil when that has findElement, findText, etc.
262: NodeList nl = data
263: .getElementsByTagNameNS(
264: UMLProjectType.PROJECT_CONFIGURATION_NAMESPACE,
265: "name"); // NOI18N
266:
267: if (nl.getLength() == 1) {
268: nl = nl.item(0).getChildNodes();
269: if (nl.getLength() == 1
270: && nl.item(0).getNodeType() == Node.TEXT_NODE) {
271: return ((Text) nl.item(0))
272: .getNodeValue();
273: }
274: }
275: return "???"; // NOI18N
276: }
277: });
278: }
279:
280: public void setName(final String name) {
281: ProjectManager.mutex().writeAccess(new Mutex.Action() {
282: public Object run() {
283: Element data = mHelper
284: .getPrimaryConfigurationData(true);
285:
286: // XXX replace by XMLUtil when that has findElement, findText, etc.
287: NodeList nl = data.getElementsByTagNameNS(
288: UMLProjectType.PROJECT_CONFIGURATION_NAMESPACE,
289: "name"); // NOI18N
290:
291: Element nameEl;
292: if (nl.getLength() == 1) {
293: nameEl = (Element) nl.item(0);
294: NodeList deadKids = nameEl.getChildNodes();
295:
296: while (deadKids.getLength() > 0) {
297: nameEl.removeChild(deadKids.item(0));
298: }
299: }
300:
301: else {
302: nameEl = data
303: .getOwnerDocument()
304: .createElementNS(
305: UMLProjectType.PROJECT_CONFIGURATION_NAMESPACE,
306: "name"); // NOI18N
307:
308: data.insertBefore(nameEl, data.getChildNodes()
309: .item(0));
310: }
311:
312: nameEl.appendChild(data.getOwnerDocument()
313: .createTextNode(name));
314: mHelper.putPrimaryConfigurationData(data, true);
315: return null;
316: }
317: });
318: }
319:
320: protected void retrieveFilenames(File fileObj, IStrings filenames,
321: ILanguageManager manager) {
322: if (fileObj != null) {
323: if (fileObj.isDirectory() == true) {
324: File[] children = fileObj.listFiles();
325: for (int index = 0; index < children.length; index++) {
326: retrieveFilenames(children[index], filenames,
327: manager);
328: }
329: } else {
330: String path = fileObj.getAbsolutePath();
331: if (manager.getLanguageForFile(path) != null) {
332: filenames.add(path);
333: }
334: }
335: }
336: }
337:
338: protected IStrings retrieveFilenames(File[] files) {
339:
340: IStrings retVal = new Strings();
341:
342: try {
343: ILanguageManager manager = mHelper.getProduct()
344: .getLanguageManager();
345: for (int index = 0; index < files.length; index++) {
346: retrieveFilenames(files[index], retVal, manager);
347: }
348: } catch (Throwable t) {
349: t.printStackTrace();
350: }
351: return retVal;
352: }
353:
354: public void reverseEngineer(File[] sourceFolders) {
355: initalizeProperties();
356: IStrings files = retrieveFilenames(sourceFolders);
357:
358: ReverseEngineerTask reTask = new ReverseEngineerTask(mHelper
359: .getProject(), files, false, false, true, true,
360: new ITaskFinishListener() {
361:
362: public void taskFinished() {
363: SwingUtilities.invokeLater(new Runnable() {
364: public void run() {
365: UMLPhysicalViewProvider provider = (UMLPhysicalViewProvider) UMLProject.this
366: .getLookup()
367: .lookup(
368: UMLPhysicalViewProvider.class);
369: if (provider != null) {
370: ModelRootNodeCookie cookie = provider
371: .getModelRootNodeCookie();
372:
373: if (cookie != null)
374: cookie.recalculateChildren();
375: }
376: }
377: });
378: }
379: });
380:
381: RequestProcessor processor = new RequestProcessor(
382: "uml/ReverseEngineer"); // NOI18N
383:
384: processor.post(reTask);
385:
386: // final IUMLParsingIntegrator integrator = new UMLParsingIntegrator();
387: // integrator.setFiles(files);
388: // integrator.reverseEngineer(mHelper.getProject(),
389: // false, // this brings up the file chooser
390: // false, // this should be false for now.
391: // true, // this will display the progress dialog,
392: // true); // this will cause all the classes to
393: // // be created in their own file. Not
394: // // currently enabled
395: }
396:
397: ////////////////////////////////////////////////////////////////////////////
398: // AntProjectListener Implementation
399:
400: public void configurationXmlChanged(AntProjectEvent event) {
401: if (event.getPath().equals(AntProjectHelper.PROJECT_XML_PATH)) {
402: // Could be various kinds of changes, but name
403: // & displayName might have changed.
404: Info info = (Info) getLookup().lookup(
405: ProjectInformation.class);
406: info.firePropertyChange(ProjectInformation.PROP_NAME);
407: info
408: .firePropertyChange(ProjectInformation.PROP_DISPLAY_NAME);
409: }
410: }
411:
412: public void propertiesChanged(AntProjectEvent antProjectEvent) {
413: // currently ignored (probably better to listen to
414: // evaluator() if you need to)
415: }
416:
417: // MCF - added in desperation. Not sure of best location for "save", jeez
418: public void saveProject() {
419: mHelper.saveProject();
420: }
421:
422: protected void initalizeProperties() {
423: // MCF I am not sure if this is bad practice, but I don't see the
424: // point in reading the properties constantly. Our AssociatedSourceProvider
425: // will need to access the referenced project stuff constantly.
426: // So I would like to store the reference to the properties for
427: // better performance. It does mean that we have to be careful to
428: // keep the reference in sync with the one the Customizer uses.
429: if (uiProperties == null) {
430: uiProperties = new UMLProjectProperties(UMLProject.this ,
431: mHelper, mEval, mRefHelper);
432: }
433: }
434:
435: protected void initializeProjectSettings(IProject project) {
436: if (getUMLProjectProperties() != null) {
437: String mode = getUMLProjectProperties().getProjectMode();
438: if (mode.equals(project.getMode()) == false) {
439: setProjectMode(project, mode);
440: }
441: }
442: }
443:
444: /**
445: * Sets the projects mode. The mode is used to control the round trip
446: * behavior.
447: */
448: public void setProjectMode(String newMode) {
449: IProject project = mHelper.getProject();
450: setProjectMode(project, newMode);
451:
452: }
453:
454: protected void setProjectMode(IProject project, String newMode) {
455: if (project != null) {
456: project.setMode(newMode);
457: }
458: }
459:
460: ////////////////////////////////////////////////////////////////////////////
461: // Heper Classes
462:
463: private final class ProjectOpenedHookImpl extends ProjectOpenedHook {
464: UMLProjectChangeListener listener = new UMLProjectChangeListener();
465:
466: ProjectOpenedHookImpl() {
467: }
468:
469: /**
470: * Retrieves the project from the project helepr. If the project has retrieved it
471: * is initialized.
472: */
473: protected IProject retreiveProject() {
474: IProject retVal = null;
475:
476: try {
477: retVal = mHelper.getProject();
478: initializeProjectSettings(retVal);
479: mImportSupport.initializeProject();
480: } catch (Exception e) {
481: ErrorManager.getDefault().notify(e);
482: }
483:
484: return retVal;
485: }
486:
487: /**
488: * Retreives the project and verifies that the project is valid.
489: * The project needs be verified because the product is initialized
490: * in a different thread than the thread that opens projects. Therefore,
491: * we need to make sure that the UML product has been initialized before
492: * the project is created.
493: */
494: private IProject temp = null;
495:
496: protected IProject verifyProjectIsInitialized() {
497: temp = retreiveProject();
498:
499: while (temp == null) {
500: try {
501: SwingUtilities.invokeAndWait(new Runnable() {
502: public void run() {
503: temp = retreiveProject();
504: }
505: });
506: } catch (Exception e) {
507: // Ignore interrupt messages.
508: }
509: }
510:
511: return temp;
512: }
513:
514: protected void projectOpened() {
515: // Cause the helper to initialize the project if it has not already
516: // done so.
517: // RequestProcessor.getDefault().post(new Runnable()
518: // {
519: // public void run()
520: // {
521: // IProject project = mHelper.getProject();
522: // initializeProjectSettings(project);
523: // }
524: // });
525:
526: IProject project = verifyProjectIsInitialized();
527:
528: // Check up on build scripts.
529: // nothing for us yet
530:
531: // register project's classpaths to GlobalPathRegistry
532: // nothing for us yet
533:
534: //register updater of main.class
535: //the updater is active only on the opened projects
536: // nothing for us yet
537:
538: // Make it easier to run headless builds on the same machine at least.
539: ProjectManager.mutex().writeAccess(new Mutex.Action() {
540: public Object run() {
541: EditableProperties ep = mHelper
542: .getProperties(AntProjectHelper.PRIVATE_PROPERTIES_PATH);
543: File buildProperties = new File(System
544: .getProperty("netbeans.user"),
545: "build.properties"); // NOI18N
546: ep.setProperty("user.properties.file", // NOI18N
547: buildProperties.getAbsolutePath());
548: mHelper.putProperties(
549: AntProjectHelper.PRIVATE_PROPERTIES_PATH,
550: ep);
551:
552: try {
553: ProjectManager.getDefault().saveProject(
554: UMLProject.this );
555:
556: }
557:
558: catch (IOException e) {
559: ErrorManager.getDefault().notify(e);
560: }
561:
562: return null;
563: }
564: });
565:
566: UMLPhysicalViewProvider physicalViewProvider = (UMLPhysicalViewProvider) UMLProject.this
567: .getLookup().lookup(UMLPhysicalViewProvider.class);
568:
569: boolean broken = physicalViewProvider.hasBrokenLinks();
570: if (physicalViewProvider != null && (broken == true)) {
571: BrokenReferencesSupport.showAlert();
572: }
573:
574: initalizeProperties();
575:
576: FileObject dobj = mHelper.getProjectDirectory();
577:
578: if (dobj != null) {
579: Project currentUMLProj = FileOwnerQuery.getOwner(dobj);
580: String filename = dobj.getPath();
581: if (filename != null && filename.length() > 0) {
582: filename = normalizeFile(FileUtil.toFile(dobj)
583: .getPath());
584: }
585: org.netbeans.modules.uml.core.metamodel.structure.Project.PROJ_BASE_DIR = filename;
586:
587: if (broken == false) {
588: UMLProjectHelper
589: .scanSourceGroups((UMLProject) currentUMLProj);
590: }
591: if (project instanceof org.netbeans.modules.uml.core.metamodel.structure.Project) {
592: ((org.netbeans.modules.uml.core.metamodel.structure.Project) project)
593: .addPropertyChangeListener(listener);
594: }
595: try {
596: File prjFile = new File(project.getProject()
597: .getFileName());
598: FileObject fobj = FileUtil.toFileObject(new File(
599: prjFile.getCanonicalPath()));
600: obj = DataObject.find(fobj);
601: if (project.getDirty()) {
602: ((UMLProjectDataObject) obj).addSaveCookie();
603: obj.setModified(true);
604: }
605: } catch (Exception e) {
606: ErrorManager.getDefault().log(
607: ErrorManager.EXCEPTION, e.getMessage());
608: }
609: }
610: }
611:
612: public String normalizeFile(String filename) {
613: if (filename != null && filename.length() > 0)
614: filename = filename.replace("/", File.separator).trim(); // NOI18N
615:
616: return filename;
617: }
618:
619: protected void projectClosed() {
620: if (mHelper != null)
621: mHelper.closeProject(false);
622:
623: if (mImportSupport != null)
624: mImportSupport.unInitializeProject();
625:
626: Lookup l = UMLProject.this .getLookup();
627: if (l != null) {
628: UMLPhysicalViewProvider physicalViewProvider = (UMLPhysicalViewProvider) l
629: .lookup(UMLPhysicalViewProvider.class);
630: if (physicalViewProvider != null)
631: physicalViewProvider.detachLogicalView();
632: }
633:
634: Project[] projects = ProjectUtil.getOpenUMLProjects();
635: // close TCs in case all uml projects are closed
636: if (projects.length == 0) {
637: SwingUtilities.invokeLater(new Runnable() {
638: public void run() {
639: TopComponent tc = WindowManager.getDefault()
640: .findTopComponent("designpattern");
641: if (tc != null)
642: tc.close();
643: tc = WindowManager.getDefault()
644: .findTopComponent("documentation");
645: if (tc != null)
646: tc.close();
647: }
648: });
649: }
650: }
651:
652: /* listen to IProject change event, and modify project file data object
653: * to enable save all button
654: */
655: private class UMLProjectChangeListener implements
656: PropertyChangeListener {
657: public void propertyChange(PropertyChangeEvent evt) {
658: if (org.netbeans.modules.uml.core.metamodel.structure.Project.PROP_DIRTY
659: .equals(evt.getPropertyName())) {
660: if (obj instanceof UMLProjectDataObject) {
661: ((UMLProjectDataObject) obj).addSaveCookie();
662: obj.setModified(((Boolean) evt.getNewValue())
663: .booleanValue());
664: }
665: }
666: }
667: }
668:
669: }
670:
671: // Private innerclasses ----------------------------------------------------
672:
673: private final class Info implements ProjectInformation {
674:
675: private final PropertyChangeSupport pcs = new PropertyChangeSupport(
676: this );
677:
678: Info() {
679: }
680:
681: void firePropertyChange(String prop) {
682: pcs.firePropertyChange(prop, null, null);
683: }
684:
685: public String getName() {
686: return PropertyUtils.getUsablePropertyName(UMLProject.this
687: .getName());
688: }
689:
690: public String getDisplayName() {
691: return UMLProject.this .getName();
692: }
693:
694: public Icon getIcon() {
695: return PROJECT_ICON;
696: }
697:
698: public Project getProject() {
699: return UMLProject.this ;
700: }
701:
702: public void addPropertyChangeListener(
703: PropertyChangeListener listener) {
704: pcs.addPropertyChangeListener(listener);
705: }
706:
707: public void removePropertyChangeListener(
708: PropertyChangeListener listener) {
709: pcs.removePropertyChangeListener(listener);
710: }
711:
712: }
713:
714: private static final class RecommendedTemplatesImpl implements
715: RecommendedTemplates, PrivilegedTemplates {
716: RecommendedTemplatesImpl() {
717: }
718:
719: // List of primarily supported templates
720: private static final String[] APPLICATION_TYPES = new String[] { "uml-type", // NOI18N
721: };
722:
723: private static final String[] PRIVILEGED_NAMES = new String[] {
724: "Templates/UML/newUMLDiagram", // NOI18N
725: "Templates/UML/newUMLPackage", // NOI18N
726: "Templates/UML/newUMLElement" // NOI18N
727: };
728:
729: public String[] getRecommendedTypes() {
730: return APPLICATION_TYPES;
731: }
732:
733: public String[] getPrivilegedTemplates() {
734: return PRIVILEGED_NAMES;
735: }
736: }
737:
738: final class AntProjectHelperProvider {
739: AntProjectHelper getAntProjectHelper() {
740: return mHelper.getAntProjectHelper();
741:
742: }
743: }
744:
745: /**
746: * Exports the main JAR as an official build product for use from other
747: * scripts. The type of the artifact will be {@link AntArtifact#TYPE_JAR}.
748: */
749: private final class AntArtifactProviderImpl implements
750: AntArtifactProvider {
751:
752: public AntArtifact[] getBuildArtifacts() {
753: return new AntArtifact[] { mHelper
754: .getAntProjectHelper()
755: .createSimpleAntArtifact(
756: UMLProject.ARTIFACT_TYPE_UML_PROJ,
757: UMLProjectProperties.UML_PROJECT_ANT_ARTIFACT,
758: evaluator(), "uml", "cleanUml"), // NOI18N
759: };
760: }
761: }
762: }
|