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-2006 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: package org.netbeans.modules.vmd.api.model;
042:
043: import org.netbeans.modules.vmd.model.XMLComponentDescriptor;
044: import org.netbeans.modules.vmd.model.XMLComponentProducer;
045: import org.openide.loaders.DataFolder;
046: import org.openide.xml.XMLUtil;
047: import org.openide.filesystems.FileObject;
048: import org.openide.filesystems.FileSystem;
049: import org.openide.filesystems.FileLock;
050: import org.w3c.dom.*;
051:
052: import java.util.List;
053: import java.io.IOException;
054: import java.io.OutputStream;
055:
056: /**
057: * This class contains a support for a custom component serialization into a xml file which is automatically stored into the global registry.
058: *
059: * @author David Kaspar
060: */
061: public class ComponentSerializationSupport {
062:
063: /**
064: * Invokes refreshing of descriptor registry of a specified project type.
065: * @param projectType the project type
066: */
067: public static void refreshDescriptorRegistry(String projectType) {
068: GlobalDescriptorRegistry registry = GlobalDescriptorRegistry
069: .getGlobalDescriptorRegistry(projectType);
070: DataFolder registryFolder = registry.getRegistryFolder();
071: registryFolder.getPrimaryFile().refresh(true);
072: DataFolder producersFolder = registry.getProducersFolder();
073: producersFolder.getPrimaryFile().refresh(true);
074: registry.reload();
075: }
076:
077: /**
078: * Runs a task under read access on description registry.
079: * @param projectType the project type
080: * @param runnable the task
081: */
082: public static void runUnderDescriptorRegistryReadAccess(
083: String projectType, Runnable runnable) {
084: GlobalDescriptorRegistry registry = GlobalDescriptorRegistry
085: .getGlobalDescriptorRegistry(projectType);
086: registry.readAccess(runnable);
087: }
088:
089: /**
090: * Runs a task under write access on description registry.
091: * @param projectType the project type
092: * @param runnable the task
093: */
094: public static void runUnderDescriptorRegistryWriteAccess(
095: String projectType, Runnable runnable) {
096: GlobalDescriptorRegistry registry = GlobalDescriptorRegistry
097: .getGlobalDescriptorRegistry(projectType);
098: registry.writeAccess(runnable);
099: }
100:
101: /**
102: * Creates a new component descriptor and stores it into xml file and add it into global descriptor registry.
103: * After you add all custom component descriptors, then call <code>ComponentSerializationSupport.refresh</code> to refresh the registry.
104: * @param projectType the project type
105: * @param typeDescriptor the type descriptor
106: * @param paletteDescriptor the palette descriptor
107: * @param properties the list of declared properties
108: * @param presenters the list of presenter serializers
109: */
110: public static void serialize(String projectType,
111: TypeDescriptor typeDescriptor,
112: PaletteDescriptor paletteDescriptor,
113: List<PropertyDescriptor> properties,
114: List<PresenterSerializer> presenters) {
115: assert projectType != null && typeDescriptor != null
116: && properties != null && presenters != null;
117:
118: serializeComponentDescriptor(projectType, typeDescriptor, null,
119: properties, presenters);
120: if (typeDescriptor.isCanInstantiate())
121: serializeComponentProducer(projectType, typeDescriptor
122: .getThisType(), paletteDescriptor);
123: }
124:
125: private static void serializeComponentDescriptor(
126: String projectType, TypeDescriptor typeDescriptor,
127: PaletteDescriptor paletteDescriptor,
128: List<PropertyDescriptor> properties,
129: List<PresenterSerializer> presenters) {
130: Document document = XMLUtil.createDocument(
131: XMLComponentDescriptor.COMPONENT_DESCRIPTOR_NODE, null,
132: null, null);
133: Node rootNode = document.getFirstChild();
134: setAttribute(document, rootNode,
135: XMLComponentDescriptor.VERSION_ATTR,
136: XMLComponentDescriptor.VERSION_VALUE_1);
137:
138: Element typeNode = document
139: .createElement(XMLComponentDescriptor.TYPE_NODE);
140: if (typeDescriptor.getSuperType() != null)
141: setAttribute(document, typeNode,
142: XMLComponentDescriptor.SUPER_TYPEID_ATTR,
143: typeDescriptor.getSuperType().toString());
144: setAttribute(document, typeNode,
145: XMLComponentDescriptor.THIS_TYPEID_ATTR, typeDescriptor
146: .getThisType().toString());
147: setAttribute(document, typeNode,
148: XMLComponentDescriptor.CAN_DERIVE_ATTR, Boolean
149: .toString(typeDescriptor.isCanDerive()));
150: setAttribute(document, typeNode,
151: XMLComponentDescriptor.CAN_INSTANTIATE_ATTR, Boolean
152: .toString(typeDescriptor.isCanInstantiate()));
153: rootNode.appendChild(typeNode);
154:
155: if (paletteDescriptor != null) {
156: Element paletteNode = document
157: .createElement(XMLComponentDescriptor.PALETTE_NODE);
158: setAttribute(document, paletteNode,
159: XMLComponentDescriptor.DISPLAY_NAME_ATTR,
160: paletteDescriptor.getDisplayName());
161: if (paletteDescriptor.getToolTip() != null)
162: setAttribute(document, paletteNode,
163: XMLComponentDescriptor.TOOLTIP_ATTR,
164: paletteDescriptor.getToolTip());
165: if (paletteDescriptor.getCategoryID() != null)
166: setAttribute(
167: document,
168: paletteNode,
169: XMLComponentDescriptor.PREFERRED_CATEGORYID_ATTR,
170: paletteDescriptor.getCategoryID());
171: if (paletteDescriptor.getSmallIcon() != null)
172: setAttribute(document, paletteNode,
173: XMLComponentDescriptor.SMALL_ICON_ATTR,
174: paletteDescriptor.getSmallIcon());
175: if (paletteDescriptor.getLargeIcon() != null)
176: setAttribute(document, paletteNode,
177: XMLComponentDescriptor.LARGE_ICON_ATTR,
178: paletteDescriptor.getLargeIcon());
179: rootNode.appendChild(paletteNode);
180: }
181:
182: for (PropertyDescriptor propertyDescriptor : properties) {
183: assert propertyDescriptor != null;
184: Element propertyNode = document
185: .createElement(XMLComponentDescriptor.PROPERTY_DESCRIPTOR_NODE);
186: setAttribute(document, propertyNode,
187: XMLComponentDescriptor.NAME_ATTR,
188: propertyDescriptor.getName());
189: setAttribute(document, propertyNode,
190: XMLComponentDescriptor.TYPEID_ATTR,
191: propertyDescriptor.getType().toString());
192: String userCode = propertyDescriptor.getDefaultValue()
193: .getUserCode();
194: if (userCode != null)
195: setAttribute(document, propertyNode,
196: XMLComponentDescriptor.DEFAULT_VALUE_ATTR,
197: userCode);
198: setAttribute(document, propertyNode,
199: XMLComponentDescriptor.ALLOW_NULL, Boolean
200: .toString(propertyDescriptor.isAllowNull()));
201: setAttribute(document, propertyNode,
202: XMLComponentDescriptor.ALLOW_USER_CODE, Boolean
203: .toString(propertyDescriptor
204: .isAllowUserCode()));
205: setAttribute(document, propertyNode,
206: XMLComponentDescriptor.USE_FOR_SERIALIZATION_ATTR,
207: Boolean.toString(propertyDescriptor
208: .isUseForSerialization()));
209: setAttribute(document, propertyNode,
210: XMLComponentDescriptor.READ_ONLY_ATTR, Boolean
211: .toString(propertyDescriptor.isReadOnly()));
212: rootNode.appendChild(propertyNode);
213: }
214:
215: Element presentersNode = document
216: .createElement(XMLComponentDescriptor.PRESENTERS_NODE);
217: for (PresenterSerializer serializer : presenters) {
218: List<Element> nodes = serializer.serialize(document);
219: if (nodes != null)
220: for (Node node : nodes) {
221: if (node != null)
222: presentersNode.appendChild(node);
223: }
224: }
225: rootNode.appendChild(presentersNode);
226:
227: GlobalDescriptorRegistry registry = GlobalDescriptorRegistry
228: .getGlobalDescriptorRegistry(projectType);
229: DataFolder registryFolder = registry.getRegistryFolder();
230: if (!writeDocument(registryFolder.getPrimaryFile(),
231: typeDescriptor.getThisType().toString(), "xml",
232: document)) // NOI18N
233: Debug.warning(
234: "Error while serializing a component descriptor",
235: typeDescriptor.getThisType().toString()); // NOI18N
236: }
237:
238: private static void serializeComponentProducer(String projectType,
239: TypeID typeID, PaletteDescriptor paletteDescriptor) {
240: Document document = XMLUtil.createDocument(
241: XMLComponentProducer.COMPONENT_PRODUCER_NODE, null,
242: null, null);
243: Node rootNode = document.getFirstChild();
244: setAttribute(document, rootNode,
245: XMLComponentProducer.VERSION_ATTR,
246: XMLComponentProducer.VERSION_VALUE_1);
247:
248: setAttribute(document, rootNode,
249: XMLComponentProducer.PRODUCERID_ATTR, typeID.toString());
250: setAttribute(document, rootNode,
251: XMLComponentProducer.MAIN_COMPONENT_TYPEID_ATTR, typeID
252: .toString());
253:
254: setAttribute(document, rootNode,
255: XMLComponentProducer.DISPLAY_NAME_ATTR,
256: paletteDescriptor.getDisplayName());
257: if (paletteDescriptor.getToolTip() != null)
258: setAttribute(document, rootNode,
259: XMLComponentProducer.TOOLTIP_ATTR,
260: paletteDescriptor.getToolTip());
261: if (paletteDescriptor.getCategoryID() != null)
262: setAttribute(document, rootNode,
263: XMLComponentProducer.PREFERRED_CATEGORYID_ATTR,
264: paletteDescriptor.getCategoryID());
265: if (paletteDescriptor.getSmallIcon() != null)
266: setAttribute(document, rootNode,
267: XMLComponentDescriptor.SMALL_ICON_ATTR,
268: paletteDescriptor.getSmallIcon());
269: if (paletteDescriptor.getLargeIcon() != null)
270: setAttribute(document, rootNode,
271: XMLComponentDescriptor.LARGE_ICON_ATTR,
272: paletteDescriptor.getLargeIcon());
273:
274: GlobalDescriptorRegistry registry = GlobalDescriptorRegistry
275: .getGlobalDescriptorRegistry(projectType);
276: DataFolder producersFolder = registry.getProducersFolder();
277: if (!writeDocument(producersFolder.getPrimaryFile(), typeID
278: .toString(), "xml", document)) // NOI18N
279: Debug.warning(
280: "Error while serializing a component producer",
281: typeID.toString()); // NOI18N
282: }
283:
284: private static void setAttribute(Document xml, Node node,
285: String name, String value) {
286: NamedNodeMap map = node.getAttributes();
287: Attr attribute = xml.createAttribute(name);
288: attribute.setValue(value);
289: map.setNamedItem(attribute);
290: }
291:
292: public static boolean writeDocument(final FileObject folder,
293: final String filename, final String ext, final Document doc) {
294: try {
295: folder.getFileSystem().runAtomicAction(
296: new FileSystem.AtomicAction() {
297: public void run() throws IOException {
298: FileObject file = folder.getFileObject(
299: filename, ext);
300: if (file == null)
301: file = folder.createData(filename, ext);
302: writeDocument(file, doc);
303: }
304: });
305: return true;
306: } catch (IOException e) {
307: e.printStackTrace();
308: return false;
309: }
310: }
311:
312: public static void writeDocument(FileObject file, Document doc)
313: throws IOException {
314: if (file == null)
315: throw new IOException("Null file to write document"); // NOI18N
316: if (doc == null)
317: throw new IOException("Empty document is about to save"); // NOI18N
318: OutputStream os = null;
319: FileLock lock = null;
320: try {
321: lock = file.lock();
322: os = file.getOutputStream(lock);
323: XMLUtil.write(doc, os, "UTF-8"); // NOI18N
324: } finally {
325: if (os != null)
326: try {
327: os.close();
328: } catch (IOException e) {
329: }
330: if (lock != null)
331: lock.releaseLock();
332: }
333: }
334:
335: }
|