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.core.metamodel.profiles;
043:
044: import org.dom4j.Document;
045: import org.dom4j.Element;
046: import org.dom4j.Node;
047:
048: import org.netbeans.modules.uml.common.generics.ETPairT;
049: import org.netbeans.modules.uml.common.generics.ETTripleT;
050: import org.netbeans.modules.uml.core.coreapplication.ICoreProduct;
051: import org.netbeans.modules.uml.core.coreapplication.IPreferenceManager2;
052: import org.netbeans.modules.uml.core.metamodel.core.foundation.IConfigManager;
053: import org.netbeans.modules.uml.core.metamodel.core.foundation.IElement;
054: import org.netbeans.modules.uml.core.metamodel.core.foundation.IPackage;
055: import org.netbeans.modules.uml.core.metamodel.core.foundation.IPackageImport;
056: import org.netbeans.modules.uml.core.metamodel.core.foundation.TypedFactoryRetriever;
057: import org.netbeans.modules.uml.core.metamodel.core.foundation.UMLXMLManip;
058: import org.netbeans.modules.uml.core.metamodel.infrastructure.coreinfrastructure.StructureConstants;
059: import org.netbeans.modules.uml.core.metamodel.structure.IProject;
060: import org.netbeans.modules.uml.core.metamodel.structure.XMLFragmentLoader;
061: import org.netbeans.modules.uml.core.support.umlsupport.PathManip;
062: import org.netbeans.modules.uml.core.support.umlsupport.ProductRetriever;
063: import org.netbeans.modules.uml.core.support.umlsupport.StringUtilities;
064: import org.netbeans.modules.uml.core.support.umlsupport.XMLManip;
065:
066: /**
067: * @author sumitabhk
068: *
069: */
070: public class ProfileManager {
071:
072: /**
073: *
074: */
075: public ProfileManager() {
076: super ();
077: }
078:
079: /**
080: *
081: * Creates a new Stereotype with the given name. Dependent on preference settings, that stereotype
082: * will be placed in a Profile that is then imported by the Project that owns context.
083: *
084: * @param context[in] Used to retrieve the IProject that will have the potentially new Profile injected
085: * into it
086: * @param stereotypeName[in] The name of the new stereotype
087: * @param newStereotype[out] The newly created Stereotype
088: *
089: * @return HRESULT
090: *
091: */
092: public Object establishNewStereotype(IElement context, String name) {
093: IStereotype newStereo = null;
094: IProject proj = context.getProject();
095: if (proj != null) {
096: String href = null;
097: //Here proceed is passed by ref. so any modification inside the method,
098: //would reflect here as well.
099: ETTripleT<String, IProfile, Boolean> retValue = retrieveAutoCreatedProfile(proj);
100: href = retValue.getParamOne();
101: IProfile prof = retValue.getParamTwo();
102: Boolean proceed = retValue.getParamThree();
103: if (proceed != null && proceed.booleanValue()
104: && prof != null) {
105: IPackageImport packImp = proj.importPackage(prof, href,
106: true);
107: if (packImp != null) {
108: // Now mark the PackageImport with a tagged value for
109: // easy retrieval later
110: packImp.addTaggedValue("autoCreated", "true");
111:
112: prof = null;
113: // Need to retrieve the package import in this case, in order to make sure that
114: // the Profile is reimported, ensuring that the element in memory is loaded properly
115: IPackage pack = packImp.getImportedPackage();
116: if (pack instanceof IProfile) {
117: prof = (IProfile) pack;
118: }
119: }
120: }
121:
122: if (prof != null) {
123: // Now, create the new Stereotype
124: TypedFactoryRetriever<IStereotype> ret = new TypedFactoryRetriever<IStereotype>();
125: newStereo = ret.createType("Stereotype");
126: if (newStereo != null) {
127: newStereo.setName(name);
128: prof.addOwnedElement(newStereo);
129: }
130: }
131: }
132: return newStereo;
133: }
134:
135: /**
136: *
137: * Retrieves the imported Profile from the Project, else creates one if it is not there.a
138: *
139: * @param proj[in] The IProject we are querying against
140: * @return ETTripleT returns an object of href, profile and the success of this method
141: */
142: protected ETTripleT<String, IProfile, Boolean> retrieveAutoCreatedProfile(
143: IProject proj) {
144: boolean wasCreated = false;
145: String href = null;
146: ETTripleT<String, IProfile, Boolean> retTriple = new ETTripleT<String, IProfile, Boolean>();
147: if (proj != null) {
148: IProfile prof = null;
149: String query = "./UML:Package.packageImport/UML:PackageImport/UML:Element.ownedElement/UML:TaggedValue[@name=\"autoCreated\"]/ancestor::*[2]";
150: Node node = proj.getNode();
151: if (node != null) {
152: Node importNode = node.selectSingleNode(query);
153: if (importNode != null) {
154: String nodeName = importNode.getName();
155: TypedFactoryRetriever<IPackageImport> ret = new TypedFactoryRetriever<IPackageImport>();
156: IPackageImport packImport = ret
157: .createTypeAndFill(importNode);
158: if (packImport != null) {
159: IPackage pack = packImport.getImportedPackage();
160: if (pack instanceof IProfile) {
161: prof = (IProfile) pack;
162: }
163: if (prof != null) {
164: Node profNode = prof.getNode();
165: if (profNode != null) {
166: href = XMLManip.getAttributeValue(
167: profNode, "href");
168: }
169: }
170: }
171: retTriple.setParamOne(href);
172: retTriple.setParamTwo(prof);
173: } else {
174: //Create the Profile, and add to Project as a PackageImport
175: ETPairT<String, IProfile> retPair = createStandAloneProfile(proj);
176: retTriple.setParamOne(retPair.getParamOne());
177: retTriple.setParamTwo(retPair.getParamTwo());
178:
179: wasCreated = true;
180: }
181: }
182: }
183: retTriple.setParamThree(Boolean.valueOf(wasCreated));
184: return retTriple;
185: }
186:
187: /**
188: *
189: * Creates a new Profile that exists in its own file. Where that file is
190: * placed is preference driven.
191: *
192: * @param proj[in] The IProject we are querying against. Used to establish a location
193: */
194: protected ETPairT<String, IProfile> createStandAloneProfile(
195: IProject proj) {
196: ETPairT<String, IProfile> retPair = new ETPairT<String, IProfile>();
197: IProfile prof = null;
198: String href = "";
199: try {
200: if (proj != null) {
201: ICoreProduct prod = ProductRetriever.retrieveProduct();
202: if (prod != null) {
203: IPreferenceManager2 prefMan = prod
204: .getPreferenceManager();
205: if (prefMan != null) {
206: //Need to determine where to create the new Profile
207: //kris richards - UnknownStereotypeCreate pref deleted. Set to PSK_IN_PROJECT_PROFILE
208: String prefValue = "PSK_IN_PROJECT_PROFILE";
209: String location = determineProfileLocation(
210: proj, prod, prefValue);
211: if (location != null && location.length() > 0) {
212: XMLFragmentLoader loader = new XMLFragmentLoader();
213: String xmlFrag = loader
214: .retrieveFragment(
215: ProfileManager.class,
216: StructureConstants.IDR_XMI_HEADER_WITHOUT_DTD);
217:
218: if (xmlFrag != null && xmlFrag.length() > 0) {
219: ETPairT<Document, IProfile> sapPair = createStandAloneProfile(xmlFrag);
220: Document doc = sapPair.getParamOne();
221: prof = sapPair.getParamTwo();
222: if (doc != null && prof != null) {
223: String projName = proj.getName();
224: if (projName != null
225: && projName.length() > 0) {
226: String projLoc = proj
227: .getFileName();
228: location += projName + ".etup";
229:
230: XMLManip.save(doc, location);
231:
232: href = PathManip
233: .retrieveRelativePath(
234: location,
235: projLoc);
236: String xmiID = prof.getXMIID();
237:
238: href += "#//*[@xmi.id='";
239: href += xmiID;
240: href += "']";
241: }
242: }
243: }
244: }
245: }
246: }
247: }
248: } catch (Exception e) {
249: //not doing anything for now.
250: }
251:
252: retPair.setParamOne(href);
253: retPair.setParamTwo(prof);
254: return retPair;
255: }
256:
257: /**
258: *
259: * Determines the location of a new Profile given the preference value passed in.
260: *
261: * @param proj[in] Could be used to anchor the location with the Project
262: * @param prod[in] Could be used to determine the default configuration location
263: * @param value[in] The preference value. Should be "PSK_IN_PROJECT_PROFILE" or
264: * "PSK_IN_CENTRAL_PROFILE", otherwise, no location will be retrieved
265: */
266: protected String determineProfileLocation(IProject proj,
267: ICoreProduct prod, String value) {
268: String location = null;
269: if (value != null) {
270: if (proj != null && value.equals("PSK_IN_PROJECT_PROFILE")) {
271: String fileName = proj.getFileName();
272: if (fileName != null && fileName.length() > 0) {
273: location = StringUtilities.getPath(fileName);
274: }
275: } else if (prod != null
276: && value.equals("PSK_IN_CENTRAL_PROFILE")) {
277: IConfigManager config = prod.getConfigManager();
278: if (config != null) {
279: location = config.getDefaultConfigLocation();
280: }
281: }
282: }
283: return location;
284: }
285:
286: /**
287: *
288: * Creates a Profile object and places it in the XML document that will be created
289: * from the fragment passed in.
290: *
291: * @param frag[in] The XML fragment that will house the Profile
292: */
293: protected ETPairT<Document, IProfile> createStandAloneProfile(
294: String frag) {
295: ETPairT<Document, IProfile> retPair = new ETPairT<Document, IProfile>();
296: IProfile prof = null;
297: Document doc = null;
298:
299: try {
300: doc = XMLManip.loadXML(frag);
301: if (doc != null) {
302: TypedFactoryRetriever<IProfile> retr = new TypedFactoryRetriever<IProfile>();
303: prof = retr.createType("Profile");
304: if (prof != null) {
305: Node node = prof.getNode();
306: String query = "XMI/XMI.content";
307: Node contentNode = doc.selectSingleNode(query);
308: Element element = (Element) contentNode;
309: if (element != null) {
310: node.detach();
311: element.add(node);
312: //UMLXMLManip.appendChild(element,node);
313: }
314: }
315: } else {
316: //throw Exception.
317: }
318: } catch (Exception e) {
319: //Not doing anything for now
320: }
321: retPair.setParamOne(doc);
322: retPair.setParamTwo(prof);
323:
324: return retPair;
325: }
326: }
|