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: package org.netbeans.modules.uml.project.ui.customizer;
043:
044: import java.io.File;
045: import java.io.IOException;
046: import java.util.ArrayList;
047: import java.util.Arrays;
048: import java.util.HashSet;
049: import java.util.List;
050: import java.util.Set;
051: import javax.swing.ComboBoxModel;
052: import javax.swing.table.DefaultTableModel;
053:
054: import org.netbeans.modules.uml.project.UMLProject;
055: import org.netbeans.modules.uml.project.UMLProjectGenerator;
056: import org.netbeans.modules.uml.project.UMLProjectHelper;
057: import org.netbeans.modules.uml.project.ui.common.CommonUiSupport;
058: import org.netbeans.modules.uml.project.ui.common.JavaSourceRootsUI.JavaSourceRootsModel;
059: import org.netbeans.modules.uml.project.ui.common.ReferencedJavaProjectModel;
060: import org.netbeans.modules.uml.project.ui.common.ReferencedJavaProjectSupport;
061:
062: import org.netbeans.api.project.ProjectManager;
063: import org.netbeans.api.project.Project;
064: import org.netbeans.modules.uml.util.StringTokenizer2;
065: import org.netbeans.spi.project.support.ant.AntProjectHelper;
066: import org.netbeans.spi.project.support.ant.EditableProperties;
067: import org.netbeans.spi.project.support.ant.PropertyEvaluator;
068: import org.netbeans.spi.project.support.ant.PropertyUtils;
069: import org.netbeans.spi.project.support.ant.ReferenceHelper;
070: import org.netbeans.spi.project.support.ant.ui.StoreGroup;
071:
072: import org.openide.ErrorManager;
073: import org.openide.filesystems.FileUtil;
074: import org.openide.util.Mutex;
075: import org.openide.util.MutexException;
076:
077: /**
078: * @author Mike Frisino
079: */
080: public class UMLProjectProperties {
081: // Special properties of the project, stored in project.xml by project.save
082:
083: // Properties stored in the PROJECT.PROPERTIES
084: public static final String MODELING_MODE = "uml.modeling.mode"; // NOI18N
085: public static final String UML_PROJECT_ANT_ARTIFACT = "uml.umlproject"; // NOI18N
086: public static final String ANT_ARTIFACT_PREFIX = "${reference."; // NOI18N
087: public static final String REFERENCED_JAVA_PROJECT = "uml.javaproject"; // NOI18N
088: public static final String REFERENCED_JAVA_PROJECT_ARTIFACTS = "uml.javaproject.artifacts"; // NOI18N
089: public static final String REFERENCED_JAVA_PROJECT_SRC = "uml.javaproject.src"; // NOI18N
090: public static final String UML_PROJECT_IMPORTS = "uml.imports"; // NOI18N
091: public static final String UML_ARTIFACT_PREFIX = "${uml.reference."; // NOI18N
092: public static final String CODE_GEN_FOLDER_LOCATION = "code.gen.folder.location"; // NOI18N
093: public static final String CODE_GEN_TEMPLATES = "code.gen.templates"; // NOI18N
094: public static final String CODE_GEN_BACKUP_SOURCES = "code.gen.backup.sources"; // NOI18N
095: public static final String CODE_GEN_USE_MARKERS = "code.gen.use.markers"; // NOI18N
096: public static final String CODE_GEN_ADD_MARKERS = "code.gen.add.markers"; // NOI18N
097: public static final String CODE_GEN_SHOW_DIALOG = "code.gen.show.dialog"; // NOI18N
098:
099: public static final String DEFAULT_JAVA_TEMPLATES = "Java:Basic Class|Java:Basic Interface|Java:Basic Enumeration"; // NOI18N
100:
101: // MODELS FOR VISUAL CONTROLS
102:
103: // CustomizerSources
104: public ComboBoxModel modelingModeModel;
105: public String modelingModeValue;
106: public ReferencedJavaProjectModel referencedJavaProjectModel;
107: public JavaSourceRootsModel referencedJavaSourceRootsModel;
108: public DefaultTableModel umlProjectImportsModel;
109: public String codeGenTemplates;
110: public String codeGenFolderLocation;
111: public String codeGenBackupSources;
112: public String codeGenUseMarkers;
113: public String codeGenAddMarkers;
114: public String codeGenShowDialog;
115:
116: UMLImportsSupport importsSupport;
117:
118: // CustomizerRunTest
119:
120: // Private fields ---------------------------------------------------------
121: private UMLProject project;
122: private UMLProjectHelper updateHelper;
123: private PropertyEvaluator evaluator;
124: private ReferenceHelper refHelper;
125: private ReferencedJavaProjectSupport javaRefSupport;
126:
127: private StoreGroup privateGroup;
128: private StoreGroup projectGroup;
129:
130: public UMLProject getProject() {
131: return project;
132: }
133:
134: /** Creates a new instance of UMLProjectProperties and initializes them */
135: public UMLProjectProperties(UMLProject project,
136: UMLProjectHelper updateHelper, PropertyEvaluator evaluator,
137: ReferenceHelper refHelper) {
138: this .project = project;
139: this .updateHelper = updateHelper;
140: this .evaluator = evaluator;
141: this .refHelper = refHelper;
142: this .javaRefSupport = new ReferencedJavaProjectSupport(
143: evaluator, refHelper, updateHelper
144: .getAntProjectHelper(), null,
145: ANT_ARTIFACT_PREFIX);
146:
147: this .importsSupport = new UMLImportsSupport(evaluator,
148: refHelper, updateHelper.getAntProjectHelper(),
149: UML_ARTIFACT_PREFIX);
150:
151: privateGroup = new StoreGroup();
152: projectGroup = new StoreGroup();
153:
154: init(); // Load known properties
155: }
156:
157: /** Initializes the visual models
158: */
159: public void init() {
160: // Customizer Modeling
161: // fetch the stored value
162: // SELECTED_MODELING_MODE_MODEL = projectGroup.createStringDocument(
163: // evaluator, MODELING_MODE );
164: // construct model with stored value as selected item.
165:
166: EditableProperties projectProperties = updateHelper
167: .getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH);
168:
169: modelingModeModel = CommonUiSupport
170: .createModelingModeComboBoxModel(evaluator
171: .getProperty(MODELING_MODE));
172:
173: referencedJavaProjectModel = javaRefSupport
174: .createReferencedJavaProjectModel(
175: REFERENCED_JAVA_PROJECT, evaluator
176: .getProperty(REFERENCED_JAVA_PROJECT));
177:
178: referencedJavaSourceRootsModel = javaRefSupport
179: .createReferencedJavaSourceRootsModel(
180: referencedJavaProjectModel,
181: (String) projectProperties
182: .get(REFERENCED_JAVA_PROJECT_SRC));
183:
184: umlProjectImportsModel = UMLImportsUiSupport
185: .createTableModel(importsSupport
186: .itemsIterator((String) projectProperties
187: .get(UML_PROJECT_IMPORTS)));
188:
189: codeGenFolderLocation = projectProperties
190: .get(CODE_GEN_FOLDER_LOCATION);
191: codeGenTemplates = projectProperties.get(CODE_GEN_TEMPLATES);
192: codeGenBackupSources = projectProperties
193: .get(CODE_GEN_BACKUP_SOURCES);
194: codeGenUseMarkers = projectProperties.get(CODE_GEN_USE_MARKERS);
195: codeGenAddMarkers = projectProperties.get(CODE_GEN_ADD_MARKERS);
196: codeGenShowDialog = projectProperties.get(CODE_GEN_SHOW_DIALOG);
197: }
198:
199: public void save() {
200: try {
201: // Store properties
202: ProjectManager.mutex().writeAccess(
203: new Mutex.ExceptionAction() {
204: public Object run() throws IOException {
205: storeProperties();
206: return null;
207: }
208: });
209:
210: // and save the project
211: ProjectManager.getDefault().saveProject(project);
212:
213: // MCF - I am not sure if this bad practice. But I want to
214: // avoid having to recreate props in my AssociatedSoruceProvider
215: // which will be called a lot.
216: // So I am trying to cache these properties in the project.
217: project.setUMLProjectProperties(this );
218: }
219:
220: catch (MutexException e) {
221: ErrorManager.getDefault().notify(
222: (IOException) e.getException());
223: }
224:
225: catch (IOException ex) {
226: ErrorManager.getDefault().notify(ex);
227: }
228: }
229:
230: private void storeProperties() throws IOException {
231: // Store special properties
232:
233: // Modify the project dependencies properly
234: resolveProjectDependencies();
235:
236: String[] umlImports = importsSupport
237: .encodeToStrings(UMLImportsUiSupport
238: .getIterator(umlProjectImportsModel));
239:
240: String[] refJavaSrcRoots = javaRefSupport
241: .encodeSrcGroupsToStrings(referencedJavaSourceRootsModel);
242:
243: // Store standard properties
244: EditableProperties projectProperties = updateHelper
245: .getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH);
246:
247: EditableProperties privateProperties = updateHelper
248: .getProperties(AntProjectHelper.PRIVATE_PROPERTIES_PATH);
249:
250: // Standard store of the properties
251: projectGroup.store(projectProperties);
252: privateGroup.store(privateProperties);
253:
254: projectProperties.setProperty(MODELING_MODE, getProjectMode());
255:
256: projectProperties.setProperty(REFERENCED_JAVA_PROJECT_SRC,
257: refJavaSrcRoots);
258:
259: if (codeGenFolderLocation != null)
260: projectProperties.setProperty(CODE_GEN_FOLDER_LOCATION,
261: codeGenFolderLocation);
262:
263: if (codeGenTemplates != null)
264: projectProperties.setProperty(CODE_GEN_TEMPLATES,
265: codeGenTemplates);
266:
267: if (codeGenBackupSources != null)
268: projectProperties.setProperty(CODE_GEN_BACKUP_SOURCES,
269: codeGenBackupSources);
270:
271: if (codeGenUseMarkers != null)
272: projectProperties.setProperty(CODE_GEN_USE_MARKERS,
273: codeGenUseMarkers);
274:
275: if (codeGenAddMarkers != null)
276: projectProperties.setProperty(CODE_GEN_ADD_MARKERS,
277: codeGenAddMarkers);
278:
279: if (codeGenShowDialog != null)
280: projectProperties.setProperty(CODE_GEN_SHOW_DIALOG,
281: codeGenShowDialog);
282:
283: projectProperties.setProperty(UML_PROJECT_IMPORTS, umlImports);
284:
285: // Store the property changes into the project
286: updateHelper.putProperties(
287: AntProjectHelper.PROJECT_PROPERTIES_PATH,
288: projectProperties);
289:
290: updateHelper.putProperties(
291: AntProjectHelper.PRIVATE_PROPERTIES_PATH,
292: privateProperties);
293:
294: UMLProjectGenerator.fixJavaProjectReferences(updateHelper
295: .getAntProjectHelper(), referencedJavaProjectModel
296: .getProject());
297: }
298:
299: /** Finds out what are new and removed project dependencies and
300: * applyes the info to the project
301: */
302: private void resolveProjectDependencies() {
303:
304: AntProjectHelper h = updateHelper.getAntProjectHelper();
305:
306: EditableProperties ep = updateHelper
307: .getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH);
308:
309: String oldJavaArtifactRefStr = (String) ep
310: .get(UMLProjectProperties.REFERENCED_JAVA_PROJECT_ARTIFACTS);
311:
312: if (oldJavaArtifactRefStr != null
313: && oldJavaArtifactRefStr.length() > 0) {
314:
315: String[] oldJavaArtifactRefs = new String[] { oldJavaArtifactRefStr };
316:
317: for (int i = 0; i < oldJavaArtifactRefs.length; i++) {
318: // Debug.out.println("MCF destroy reference " // NOI18N
319: // + oldJavaArtifactRefs[i]);
320: refHelper.destroyReference(oldJavaArtifactRefs[i]);
321: }
322: }
323:
324: // got to get fresh ep, after refHelper modified
325: ep = updateHelper
326: .getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH);
327:
328: // now add the new ref
329: // refHelper.addReference(artifact, uri);
330: Project javaSrcProj = referencedJavaProjectModel.getProject();
331:
332: if (javaSrcProj != null) {
333: String[] refStrs = UMLProjectGenerator.addJavaSrcProjRef(h,
334: refHelper, javaSrcProj);
335: ep = h
336: .getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH);
337: ep
338: .setProperty(
339: UMLProjectProperties.REFERENCED_JAVA_PROJECT_ARTIFACTS,
340: refStrs);
341: h.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH,
342: ep);
343: }
344:
345: // Create a set of old and new artifacts.
346: Set oldArtifacts = new HashSet();
347: Set newArtifacts = new HashSet();
348:
349: // Create set of removed artifacts and remove them
350: Set removed = new HashSet(oldArtifacts);
351: removed.removeAll(newArtifacts);
352: Set added = new HashSet(newArtifacts);
353: added.removeAll(oldArtifacts);
354:
355: // 2. now read project.properties and modify rest
356: ep = updateHelper
357: .getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH);
358:
359: boolean changed = false;
360: String javaSrcProjRefVal = ""; // NOI18N
361:
362: if (javaSrcProj != null) {
363: javaSrcProjRefVal = UMLProjectGenerator
364: .getJavaSrcProjRefVal(h, javaSrcProj);
365:
366: changed = true;
367: }
368:
369: ep.setProperty(UMLProjectProperties.REFERENCED_JAVA_PROJECT,
370: javaSrcProjRefVal);
371:
372: if (changed) {
373: updateHelper.putProperties(
374: AntProjectHelper.PROJECT_PROPERTIES_PATH, ep);
375: }
376: }
377:
378: // TODO - MCF - I kept this method from copied J2SE code, thinking we might
379: // need it or something like it. I have not yet actually used it, and if we
380: // do not use it we can delete it.
381: /**
382: * Tokenize library classpath and try to relativize all the jars.
383: * @param property library property name ala "libs.someLib.classpath"
384: * @param projectDir project dir for relativization
385: * @return relativized library classpath or null if some jar is not collocated
386: */
387: private String relativizeLibraryClasspath(String property,
388: File projectDir) {
389: String value = PropertyUtils.getGlobalProperties().getProperty(
390: property);
391: // bugfix #42852, check if the classpath
392: // property is set, otherwise return null
393: if (value == null) {
394: return null;
395: }
396:
397: String[] paths = PropertyUtils.tokenizePath(value);
398: StringBuffer sb = new StringBuffer();
399:
400: if (sb.length() == 0)
401: return null;
402:
403: else
404: return sb.toString();
405: }
406:
407: public static String getAntPropertyName(String property) {
408: if (property != null && property.startsWith("${") && // NOI18N
409: property.endsWith("}")) // NOI18N
410: {
411: return property.substring(2, property.length() - 1);
412: }
413:
414: else
415: return property;
416: }
417:
418: public String getProjectMode() {
419: return evaluator.getProperty(MODELING_MODE);
420: }
421:
422: public String getCurrentProjectMode() {
423: return evaluator.getProperty(MODELING_MODE);
424: }
425:
426: public String getCodeGenTemplates() {
427: String templates = evaluator.getProperty(CODE_GEN_TEMPLATES);
428:
429: if (templates == null)
430: templates = "";
431:
432: return templates;
433: }
434:
435: public void setCodeGenFolderLocation(String val) {
436: codeGenFolderLocation = val;
437: }
438:
439: public String getCodeGenFolderLocation() {
440: String val = evaluator.getProperty(CODE_GEN_FOLDER_LOCATION);
441:
442: if (val == null)
443: val = "";
444:
445: return val;
446: }
447:
448: public final static String TEMPLATE_DELIMITER = "|";
449:
450: public List<String> getCodeGenTemplatesArray() {
451: return new ArrayList<String>(Arrays.asList(StringTokenizer2
452: .toArray(getCodeGenTemplates(), TEMPLATE_DELIMITER))); // NOI18N
453: }
454:
455: public void setCodeGenTemplates(List<String> val) {
456: codeGenTemplates = StringTokenizer2.delimitedString(val
457: .toArray(), TEMPLATE_DELIMITER);
458: }
459:
460: public boolean isCodeGenBackupSources() {
461: String val = evaluator.getProperty(CODE_GEN_BACKUP_SOURCES);
462:
463: if (val == null)
464: val = "true"; // NOI18N
465:
466: return Boolean.valueOf(val);
467: }
468:
469: public void setCodeGenBackupSources(boolean val) {
470: codeGenBackupSources = String.valueOf(val);
471: }
472:
473: public boolean isCodeGenUseMarkers() {
474: String val = evaluator.getProperty(CODE_GEN_USE_MARKERS);
475:
476: if (val == null)
477: val = "true";
478:
479: return Boolean.valueOf(val);
480: }
481:
482: public void setCodeGenUseMarkers(boolean val) {
483: codeGenUseMarkers = String.valueOf(val);
484: }
485:
486: public boolean isCodeGenAddMarkers() {
487: String val = evaluator.getProperty(CODE_GEN_ADD_MARKERS);
488:
489: if (val == null)
490: val = "false";
491:
492: return Boolean.valueOf(val);
493: }
494:
495: public void setCodeGenAddMarkers(boolean val) {
496: codeGenAddMarkers = String.valueOf(val);
497: }
498:
499: public boolean isCodeGenShowDialog() {
500: String val = evaluator.getProperty(CODE_GEN_SHOW_DIALOG);
501:
502: if (val == null)
503: val = "true";
504:
505: return Boolean.valueOf(val);
506: }
507:
508: public void setCodeGenShowDialog(boolean val) {
509: codeGenShowDialog = String.valueOf(val);
510: }
511:
512: public File getJavaSourceRootFolder() {
513: return (referencedJavaSourceRootsModel == null
514: || referencedJavaSourceRootsModel.getSourceGroups().length == 0 || referencedJavaSourceRootsModel
515: .getSourceGroup(0) == null) ? null : FileUtil
516: .toFile(referencedJavaSourceRootsModel
517: .getSourceGroup(0).getRootFolder());
518: }
519: }
|