001: /*******************************************************************************
002: * Copyright (c) 2006, 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.ui.wizards.cheatsheet;
011:
012: import java.lang.reflect.InvocationTargetException;
013: import java.util.ArrayList;
014:
015: import org.eclipse.core.resources.IFile;
016: import org.eclipse.core.runtime.CoreException;
017: import org.eclipse.core.runtime.IProgressMonitor;
018: import org.eclipse.core.runtime.IStatus;
019: import org.eclipse.core.runtime.Status;
020: import org.eclipse.core.runtime.jobs.ISchedulingRule;
021: import org.eclipse.pde.core.IBaseModel;
022: import org.eclipse.pde.core.build.IBuild;
023: import org.eclipse.pde.core.build.IBuildEntry;
024: import org.eclipse.pde.core.build.IBuildModel;
025: import org.eclipse.pde.core.plugin.IPluginAttribute;
026: import org.eclipse.pde.core.plugin.IPluginBase;
027: import org.eclipse.pde.core.plugin.IPluginElement;
028: import org.eclipse.pde.core.plugin.IPluginExtension;
029: import org.eclipse.pde.core.plugin.IPluginModelBase;
030: import org.eclipse.pde.core.plugin.IPluginObject;
031: import org.eclipse.pde.core.plugin.ISharedExtensionsModel;
032: import org.eclipse.pde.core.plugin.PluginRegistry;
033: import org.eclipse.pde.internal.core.ClasspathUtilCore;
034: import org.eclipse.pde.internal.core.ICoreConstants;
035: import org.eclipse.pde.internal.core.TargetPlatformHelper;
036: import org.eclipse.pde.internal.core.build.BuildObject;
037: import org.eclipse.pde.internal.core.build.WorkspaceBuildModel;
038: import org.eclipse.pde.internal.core.ibundle.IBundle;
039: import org.eclipse.pde.internal.core.ibundle.IBundlePluginModelBase;
040: import org.eclipse.pde.internal.core.ibundle.IManifestHeader;
041: import org.eclipse.pde.internal.core.icheatsheet.comp.ICompCSConstants;
042: import org.eclipse.pde.internal.core.icheatsheet.simple.ISimpleCSConstants;
043: import org.eclipse.pde.internal.core.plugin.WorkspaceFragmentModel;
044: import org.eclipse.pde.internal.core.plugin.WorkspacePluginModel;
045: import org.eclipse.pde.internal.core.plugin.WorkspacePluginModelBase;
046: import org.eclipse.pde.internal.core.text.bundle.BundleSymbolicNameHeader;
047: import org.eclipse.pde.internal.core.text.bundle.RequireBundleHeader;
048: import org.eclipse.pde.internal.core.util.PDETextHelper;
049: import org.eclipse.pde.internal.ui.IPDEUIConstants;
050: import org.eclipse.pde.internal.ui.PDEPlugin;
051: import org.eclipse.pde.internal.ui.PDEUIMessages;
052: import org.eclipse.pde.internal.ui.util.ModelModification;
053: import org.eclipse.pde.internal.ui.util.PDEModelUtility;
054: import org.eclipse.swt.widgets.Shell;
055: import org.eclipse.ui.actions.WorkspaceModifyOperation;
056: import org.osgi.framework.Constants;
057:
058: /**
059: * RegisterCSOperation
060: *
061: */
062: public class RegisterCSOperation extends WorkspaceModifyOperation {
063:
064: public final static String F_CS_EXTENSION_POINT_ID = "org.eclipse.ui.cheatsheets.cheatSheetContent"; //$NON-NLS-1$
065:
066: public static final String F_CS_EXTENSION_ID = "org.eclipse.ui.cheatsheets"; //$NON-NLS-1$
067:
068: public static final String F_CS_ATTRIBUTE_CONTENT_FILE = "contentFile"; //$NON-NLS-1$
069:
070: public static final String F_CS_ATTRIBUTE_COMPOSITE = "composite"; //$NON-NLS-1$
071:
072: private IRegisterCSData fRegisterCSData;
073:
074: private Shell fShell;
075:
076: /**
077: *
078: */
079: public RegisterCSOperation(IRegisterCSData registerCSData,
080: Shell shell) {
081: fRegisterCSData = registerCSData;
082: fShell = shell;
083: }
084:
085: /**
086: * @param rule
087: */
088: public RegisterCSOperation(ISchedulingRule rule) {
089: super (rule);
090: }
091:
092: /* (non-Javadoc)
093: * @see org.eclipse.ui.actions.WorkspaceModifyOperation#execute(org.eclipse.core.runtime.IProgressMonitor)
094: */
095: protected void execute(IProgressMonitor monitor)
096: throws CoreException, InvocationTargetException,
097: InterruptedException {
098:
099: try {
100: boolean fragment = PluginRegistry.findModel(
101: fRegisterCSData.getPluginProject())
102: .isFragmentModel();
103: IFile file = fRegisterCSData.getPluginProject().getFile(
104: fragment ? ICoreConstants.FRAGMENT_PATH
105: : ICoreConstants.PLUGIN_PATH);
106: // If the plug-in exists modify it accordingly; otherwise, create
107: // a new plug-in file
108: if (file.exists()) {
109: modifyExistingPluginFile(file, monitor);
110: } else {
111: createNewPluginFile(file, monitor);
112: }
113: } catch (CoreException e) {
114: throw new InvocationTargetException(e);
115: }
116: }
117:
118: /**
119: * FindCSExtensionResult
120: *
121: */
122: private static class FindCSExtensionResult {
123:
124: public IPluginExtension fCSExtension;
125:
126: public IPluginElement fCSElement;
127:
128: /**
129: *
130: */
131: public FindCSExtensionResult() {
132: fCSExtension = null;
133: fCSElement = null;
134: }
135:
136: /**
137: * @return
138: */
139: public boolean foundCSExtension() {
140: return (fCSExtension != null);
141: }
142:
143: /**
144: * @return
145: */
146: public boolean foundExactCSElement() {
147: return (fCSElement != null);
148: }
149: }
150:
151: /**
152: * @param file
153: * @param monitor
154: * @throws CoreException
155: */
156: private void modifyExistingPluginFile(IFile file,
157: IProgressMonitor monitor) throws CoreException {
158:
159: // Validate the operation
160: // Note: This is not accurate, we are validating the plugin.xml file
161: // but not the manifest.mf file
162: IStatus status = PDEPlugin.getWorkspace().validateEdit(
163: new IFile[] { file }, fShell);
164: if (status.getSeverity() != IStatus.OK) {
165: throw new CoreException(
166: new Status(
167: IStatus.ERROR,
168: IPDEUIConstants.PLUGIN_ID,
169: IStatus.ERROR,
170: PDEUIMessages.RegisterCSOperation_errorManifestReadOnly,
171: null));
172: }
173: // Perform the modification of the plugin manifest file
174: ModelModification mod = new ModelModification(fRegisterCSData
175: .getPluginProject()) {
176: protected void modifyModel(IBaseModel model,
177: IProgressMonitor monitor) throws CoreException {
178: doModifyPluginModel(model, monitor);
179: doModifyManifestModel(model);
180: }
181: };
182: PDEModelUtility.modifyModel(mod, monitor);
183: }
184:
185: /**
186: * @param model
187: * @param monitor
188: * @throws CoreException
189: */
190: private void doModifyPluginModel(IBaseModel model,
191: IProgressMonitor monitor) throws CoreException {
192: if ((model instanceof IPluginModelBase) == false) {
193: return;
194: }
195: IPluginModelBase modelBase = (IPluginModelBase) model;
196: // Find an existing cheat sheet extension
197: FindCSExtensionResult result = findCSExtensionResult(modelBase);
198: // Check search results and act accordingly
199: if (result.foundCSExtension() && result.foundExactCSElement()) {
200: // An exact match to an existing cheat sheet element was
201: // found. Update the elements description and category
202: // fields
203: modifyExistingElement(result.fCSElement, monitor);
204: // Create the category if necessary
205: // Category element
206: IPluginElement categoryElement = createElementCategory(result.fCSExtension);
207: if (categoryElement != null) {
208: result.fCSExtension.add(categoryElement);
209: }
210: } else if (result.foundCSExtension()) {
211: // No exact match to an existing cheat sheet element found within
212: // the existing cheat sheet extension. Update the
213: // existing extension by adding a new cheat sheet element
214: // to it
215: modifyExistingExtension(result.fCSExtension, monitor);
216: } else {
217: // No existing cheat sheet extension found, create a new
218: // extension
219: insertNewExtension(modelBase, monitor);
220: }
221: }
222:
223: /**
224: * @param modelBase
225: */
226: private void insertNewExtension(IPluginModelBase modelBase,
227: IProgressMonitor monitor) throws CoreException {
228: // Update progress work units
229: monitor
230: .beginTask(
231: PDEUIMessages.RegisterCSOperation_newCSExtensionExistingPlugin,
232: 1);
233: // Create the new extension
234: IPluginExtension extension = createExtensionCheatSheet(modelBase);
235: modelBase.getPluginBase().add(extension);
236: // Update progress work units
237: monitor.done();
238: }
239:
240: /**
241: * @param extension
242: */
243: private void modifyExistingExtension(IPluginExtension extension,
244: IProgressMonitor monitor) throws CoreException {
245: // Update progress work units
246: monitor
247: .beginTask(
248: PDEUIMessages.RegisterCSOperation_modCSExtensionExistingPlugin,
249: 1);
250: // Create new children for existing extension
251: createExtensionChildren(extension);
252: // Update progress work units
253: monitor.done();
254: }
255:
256: /**
257: * @param csElement
258: * @param monitor
259: */
260: private void modifyExistingElement(IPluginElement csElement,
261: IProgressMonitor monitor) throws CoreException {
262: // Update progress work units
263: monitor
264: .beginTask(
265: PDEUIMessages.RegisterCSOperation_modCSElementExistingPlugin,
266: 1);
267: // Leave id attribute the same
268: // Update the name
269: // Attribute: name
270: csElement.setAttribute(ICompCSConstants.ATTRIBUTE_NAME,
271: fRegisterCSData.getDataCheatSheetName());
272: // Attribute: category
273: // Update the category.
274: // if "<none>" was selected, clear the entry
275: String categoryID = fRegisterCSData.getDataCategoryID();
276: if (categoryID == null) {
277: categoryID = ""; //$NON-NLS-1$
278: }
279: csElement.setAttribute(
280: RegisterCSWizardPage.F_CS_ELEMENT_CATEGORY, categoryID);
281: // Leave contentFile attribute the same
282: // Leave composite attribute the same
283: // Element: description
284: // Update an existing description if one is found; otherwise,
285: // Create a new description
286: IPluginElement descriptionElement = findExistingDescription(csElement);
287: if (descriptionElement == null) {
288: // Create a new description element
289: descriptionElement = createElementDescription(csElement);
290: if (descriptionElement != null) {
291: csElement.add(descriptionElement);
292: }
293: } else {
294: // Modify the existing description element
295: boolean modified = modifyExistingDescription(descriptionElement);
296: if (modified == false) {
297: // New description is not defined, remove the existing
298: // description element
299: csElement.remove(descriptionElement);
300: }
301: }
302: // Update progress work units
303: monitor.done();
304: }
305:
306: /**
307: * @param descriptionElement
308: */
309: private boolean modifyExistingDescription(IPluginElement element)
310: throws CoreException {
311: // If the new description is defined set it on the existing description
312: // element; otherwise, delete the existing description element
313: if (PDETextHelper.isDefinedAfterTrim(fRegisterCSData
314: .getDataDescription())) {
315: element
316: .setText(fRegisterCSData.getDataDescription()
317: .trim());
318: return true;
319: }
320: return false;
321: }
322:
323: /**
324: * @param csElement
325: * @throws CoreException
326: */
327: private IPluginElement findExistingDescription(
328: IPluginElement csElement) throws CoreException {
329:
330: if (csElement.getChildCount() > 0) {
331: IPluginObject pluginObject = csElement.getChildren()[0];
332: if (pluginObject instanceof IPluginElement) {
333: IPluginElement element = (IPluginElement) pluginObject;
334: if (element.getName().equals(
335: RegisterCSWizardPage.F_CS_ELEMENT_DESCRIPTION)) {
336: return element;
337: }
338: }
339: }
340: return null;
341: }
342:
343: /**
344: * @param model
345: * @param extensionResult cheat sheet extension found or null
346: * @param elementResult cheat sheet element found or null
347: * @return
348: */
349: private FindCSExtensionResult findCSExtensionResult(
350: IPluginModelBase model) {
351: // Container for result
352: FindCSExtensionResult result = new FindCSExtensionResult();
353: // Find all cheat sheet extensions within the host plug-in
354: IPluginExtension[] extensions = findCheatSheetExtensions(model);
355: // Process all cheat sheet extensions
356: // Extension search results
357: // (1) An existing extension containing a cheatsheet element with the
358: // exact cheat sheet ID
359: // (2) An existing extension (last one found) containing 0 or more
360: // cheatsheet or category elements
361: // (3) No existing extension
362: for (int i = 0; i < extensions.length; i++) {
363: // Cheat sheet extension match found
364: result.fCSExtension = extensions[i];
365: // Check for children
366: if (extensions[i].getChildCount() == 0) {
367: // Extension has no children, skip to the next extension
368: continue;
369: }
370: IPluginObject[] pluginObjects = extensions[i].getChildren();
371: // Process all children
372: for (int j = 0; j < pluginObjects.length; j++) {
373: if (pluginObjects[j] instanceof IPluginElement) {
374: IPluginElement element = (IPluginElement) pluginObjects[j];
375: // Find cheat sheet elements
376: if (element
377: .getName()
378: .equals(
379: RegisterCSWizardPage.F_CS_ELEMENT_CHEATSHEET)) {
380: // Cheat sheet element
381: // Get the id attribute
382: IPluginAttribute idAttribute = element
383: .getAttribute(ICompCSConstants.ATTRIBUTE_ID);
384: // Check for the generated ID for this cheat sheet
385: // element
386: if ((idAttribute != null)
387: && PDETextHelper.isDefined(idAttribute
388: .getValue())
389: && fRegisterCSData
390: .getDataCheatSheetID().equals(
391: idAttribute.getValue())) {
392: // Matching cheat sheet element found
393: result.fCSElement = element;
394: return result;
395: }
396: }
397:
398: }
399: }
400: }
401: return result;
402: }
403:
404: public static IPluginExtension[] findCheatSheetExtensions(
405: ISharedExtensionsModel model) {
406: IPluginExtension[] extensions = model.getExtensions()
407: .getExtensions();
408:
409: ArrayList csExtensions = new ArrayList();
410: for (int i = 0; i < extensions.length; i++) {
411: String point = extensions[i].getPoint();
412: if (F_CS_EXTENSION_POINT_ID.equals(point)) {
413: csExtensions.add(extensions[i]);
414: }
415: }
416: return (IPluginExtension[]) csExtensions
417: .toArray(new IPluginExtension[csExtensions.size()]);
418: }
419:
420: /**
421: * @param file
422: * @param monitor
423: */
424: private void createNewPluginFile(IFile file,
425: IProgressMonitor monitor) throws CoreException {
426:
427: // Update progress work units
428: monitor
429: .beginTask(
430: PDEUIMessages.RegisterCSOperation_addNewCSExtensionNewPlugin,
431: 4);
432: // Create the plug-in model
433: WorkspacePluginModelBase model = (WorkspacePluginModelBase) createModel(file);
434: // Update progress work units
435: monitor.worked(1);
436:
437: IPluginBase base = model.getPluginBase();
438: // Set schema version
439: double targetVersion = TargetPlatformHelper.getTargetVersion();
440: String version = null;
441: if (targetVersion < 3.2) {
442: version = ICoreConstants.TARGET30;
443: } else {
444: version = ICoreConstants.TARGET32;
445: }
446: base.setSchemaVersion(version);
447: // Create the cheat sheet extension
448: base.add(createExtensionCheatSheet(model));
449: // Update progress work units
450: monitor.worked(1);
451: // Save the model to file
452: model.save();
453: // Update progress work units
454: monitor.worked(1);
455: // Update the MANIFEST.MF file to ensure the singleton directive is set
456: // to true
457: modifyExistingManifestFile(file);
458: // Update progress work units
459: monitor.done();
460: }
461:
462: /**
463: * @param model
464: */
465: private void modifyExistingManifestFile(IFile file)
466: throws CoreException {
467: // Validate the operation
468: // Note: This is not accurate, we are validating the plugin.xml file rather
469: // than the manifest file
470: IStatus status = PDEPlugin.getWorkspace().validateEdit(
471: new IFile[] { file }, fShell);
472: if (status.getSeverity() != IStatus.OK) {
473: throw new CoreException(
474: new Status(
475: IStatus.ERROR,
476: IPDEUIConstants.PLUGIN_ID,
477: IStatus.ERROR,
478: PDEUIMessages.RegisterCSOperation_errorManifestReadOnly,
479: null));
480: }
481: // Perform the modification of the manifest file
482: ModelModification mod = new ModelModification(fRegisterCSData
483: .getPluginProject()) {
484: protected void modifyModel(IBaseModel model,
485: IProgressMonitor monitor) throws CoreException {
486: doModifyManifestModel(model);
487: doModifyBuildModel(model);
488: }
489: };
490: PDEModelUtility.modifyModel(mod, null);
491: }
492:
493: /**
494: * @param model
495: */
496: private void doModifyManifestModel(IBaseModel model) {
497: // Make sure we have a base model
498: if ((model instanceof IBundlePluginModelBase) == false) {
499: return;
500: }
501: IBundlePluginModelBase modelBase = (IBundlePluginModelBase) model;
502: IBundle bundle = modelBase.getBundleModel().getBundle();
503: // Get the heading specifying the singleton declaration
504: IManifestHeader header = bundle
505: .getManifestHeader(Constants.BUNDLE_SYMBOLICNAME);
506: if (header instanceof BundleSymbolicNameHeader) {
507: BundleSymbolicNameHeader symbolic = (BundleSymbolicNameHeader) header;
508: // If the singleton declaration is false, change it to true
509: // This is required because plug-ins that specify extensions
510: // must be singletons.
511: if (symbolic.isSingleton() == false) {
512: symbolic.setSingleton(true);
513: }
514: }
515: // Add the cheat sheets plug-in to the list of required bundles
516: header = bundle.getManifestHeader(Constants.REQUIRE_BUNDLE);
517: if (header instanceof RequireBundleHeader) {
518: RequireBundleHeader require = (RequireBundleHeader) header;
519: if (require.hasElement(F_CS_EXTENSION_ID) == false) {
520: require.addBundle(F_CS_EXTENSION_ID);
521: }
522: }
523: }
524:
525: /**
526: * @param model
527: */
528: private void doModifyBuildModel(IBaseModel model)
529: throws CoreException {
530: // Make sure we have a base model
531: if ((model instanceof IPluginModelBase) == false) {
532: return;
533: }
534: IPluginModelBase modelBase = (IPluginModelBase) model;
535: IBuild build = ClasspathUtilCore.getBuild(modelBase);
536: // Make sure we have a plugin.properties file
537: if (build == null) {
538: return;
539: }
540: // Get the entry for bin.includes
541: IBuildEntry entry = build.getEntry(IBuildEntry.BIN_INCLUDES);
542: if (entry == null) {
543: // This should never happen since the manifest.mf file exists and
544: // it has to be in the bin.includes
545: return;
546: }
547: // Add the plugin.xml file to the bin.includes build entry if it does
548: // not exist
549: if (entry.contains(ICoreConstants.PLUGIN_FILENAME_DESCRIPTOR) == false) {
550: entry.addToken(ICoreConstants.PLUGIN_FILENAME_DESCRIPTOR);
551: }
552: // There does not seem to be any support in PDEModelUtility or the
553: // ModelModification framework to save build.properties modifications
554: // As a result, explicitly do that here
555: if (build instanceof BuildObject) {
556: IBuildModel buildModel = ((BuildObject) build).getModel();
557: if (buildModel instanceof WorkspaceBuildModel) {
558: ((WorkspaceBuildModel) buildModel).save();
559: }
560: }
561: }
562:
563: /**
564: * @param file
565: * @return
566: */
567: private IPluginModelBase createModel(IFile file) {
568: if (file.getProjectRelativePath().equals(
569: ICoreConstants.FRAGMENT_PATH)) {
570: return new WorkspaceFragmentModel(file, false);
571: }
572: return new WorkspacePluginModel(file, false);
573: }
574:
575: /**
576: * @param model
577: * @return
578: * @throws CoreException
579: */
580: private IPluginExtension createExtensionCheatSheet(
581: IPluginModelBase model) throws CoreException {
582: IPluginExtension extension = model.getFactory()
583: .createExtension();
584: // Point
585: extension.setPoint(F_CS_EXTENSION_POINT_ID);
586: // NO id
587: // NO name
588:
589: createExtensionChildren(extension);
590:
591: return extension;
592: }
593:
594: /**
595: * @param extension
596: * @throws CoreException
597: */
598: private void createExtensionChildren(IPluginExtension extension)
599: throws CoreException {
600: // Category element
601: IPluginElement categoryElement = createElementCategory(extension);
602: if (categoryElement != null) {
603: extension.add(categoryElement);
604: }
605: // Cheatsheet element
606: IPluginElement cheatSheetElement = createElementCheatSheet(extension);
607: if (cheatSheetElement != null) {
608: extension.add(cheatSheetElement);
609: }
610: }
611:
612: /**
613: * @param extension
614: * @return
615: * @throws CoreException
616: */
617: private IPluginElement createElementCategory(
618: IPluginExtension extension) throws CoreException {
619: // Do not create the category if "<none>" was selected
620: String categoryID = fRegisterCSData.getDataCategoryID();
621: if (categoryID == null) {
622: return null;
623: }
624: // Do not create the category if it is an old category type
625: int type = fRegisterCSData.getDataCategoryType();
626: if (type != CSCategoryTrackerUtil.F_TYPE_NEW_CATEGORY) {
627: return null;
628: }
629: // Create the element
630: IPluginElement element = extension.getModel().getFactory()
631: .createElement(extension);
632: // Element: category
633: element.setName(RegisterCSWizardPage.F_CS_ELEMENT_CATEGORY);
634: // Attribute: id
635: element.setAttribute(ICompCSConstants.ATTRIBUTE_ID, categoryID);
636: // Attribute: name
637: // Already trimmed
638: element.setAttribute(ICompCSConstants.ATTRIBUTE_NAME,
639: fRegisterCSData.getDataCategoryName());
640:
641: return element;
642: }
643:
644: /**
645: * @param extension
646: * @return
647: * @throws CoreException
648: */
649: private IPluginElement createElementCheatSheet(
650: IPluginExtension extension) throws CoreException {
651:
652: IPluginElement element = extension.getModel().getFactory()
653: .createElement(extension);
654: // Element: cheatsheet
655: element.setName(RegisterCSWizardPage.F_CS_ELEMENT_CHEATSHEET);
656: // Attribute: id
657: element.setAttribute(ICompCSConstants.ATTRIBUTE_ID,
658: fRegisterCSData.getDataCheatSheetID());
659: // Attribute: name
660: element.setAttribute(ICompCSConstants.ATTRIBUTE_NAME,
661: fRegisterCSData.getDataCheatSheetName());
662: // Attribute: category
663: // Create the category only if "<none>" was not selected
664: String categoryID = fRegisterCSData.getDataCategoryID();
665: if (categoryID != null) {
666: element.setAttribute(
667: RegisterCSWizardPage.F_CS_ELEMENT_CATEGORY,
668: categoryID);
669: }
670: // Attribute: contentFile
671: element.setAttribute(F_CS_ATTRIBUTE_CONTENT_FILE,
672: fRegisterCSData.getDataContentFile());
673: // Attribute: composite
674: element.setAttribute(F_CS_ATTRIBUTE_COMPOSITE, Boolean
675: .toString(fRegisterCSData.isCompositeCheatSheet()));
676: // Element: description
677: IPluginElement descriptionElement = createElementDescription(element);
678: if (descriptionElement != null) {
679: element.add(descriptionElement);
680: }
681:
682: return element;
683: }
684:
685: /**
686: * @param parentElement
687: * @return
688: * @throws CoreException
689: */
690: private IPluginElement createElementDescription(
691: IPluginElement parentElement) throws CoreException {
692: // Define the description element only if description text was
693: // specified
694: String descriptionText = fRegisterCSData.getDataDescription();
695: if (PDETextHelper.isDefinedAfterTrim(descriptionText) == false) {
696: return null;
697: }
698: // Create the element
699: IPluginElement element = parentElement.getModel().getFactory()
700: .createElement(parentElement);
701: // Element: description
702: element.setName(ISimpleCSConstants.ELEMENT_DESCRIPTION);
703: // Content
704: element.setText(descriptionText.trim());
705:
706: return element;
707: }
708:
709: }
|