View Javadoc

1   /*
2    * Copyright (c) 2004-2005 by Michael Connor. All Rights Reserved.
3    *
4    * Redistribution and use in source and binary forms, with or without
5    * modification, are permitted provided that the following conditions are met:
6    *
7    *  o Redistributions of source code must retain the above copyright notice,
8    *    this list of conditions and the following disclaimer.
9    *
10   *  o Redistributions in binary form must reproduce the above copyright notice,
11   *    this list of conditions and the following disclaimer in the documentation
12   *    and/or other materials provided with the distribution.
13   *
14   *  o Neither the name of FormLayoutBuilder or Michael Connor nor the names of
15   *    its contributors may be used to endorse or promote products derived
16   *    from this software without specific prior written permission.
17   *
18   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20   * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21   * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22   * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23   * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24   * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25   * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26   * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
27   * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
28   * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29   */
30  /*
31   * ComponentDef.java
32   *
33   * Created on September 30, 2004, 5:44 PM
34   */
35  
36  package org.mlc.swing.layout;
37  
38  import java.io.IOException;
39  import java.io.InputStream;
40  import java.util.ArrayList;
41  import java.util.Collections;
42  import java.util.Enumeration;
43  import java.util.HashMap;
44  import java.util.List;
45  import java.util.Map;
46  import java.util.jar.JarEntry;
47  import java.util.jar.JarFile;
48  
49  import javax.swing.Icon;
50  import javax.xml.parsers.DocumentBuilder;
51  import javax.xml.parsers.DocumentBuilderFactory;
52  
53  import org.w3c.dom.Document;
54  import org.w3c.dom.NamedNodeMap;
55  import org.w3c.dom.Node;
56  import org.w3c.dom.NodeList;
57  
58  /***
59   * A container class for all the definition data about a Component.
60   * Instances of this class make up the component palette and are
61   * used when creating and editing component data.
62   * @author Michael Connor
63   */
64  public class ComponentDef implements Comparable<Object>
65  {
66    private static final long serialVersionUID = 1L;
67  
68    public String name = "";
69  
70    public String iconClass = "";
71  
72    public Icon icon = null;
73  
74    public String declarations = "";
75  
76    public String configure = "";
77  
78    public String add = "";
79  
80    public String remove = "";
81  
82    public String imports = "";
83  
84    public String preview = "";
85  
86    public boolean isContainer = false;
87  
88    private String description = "";
89    public String getDescription() { return description; }
90  
91    public ComponentDef()
92    {
93    }
94  
95  // Stolen from Xerces 2.5.0 code - need to replace java 1.5 getTextContent method
96      final boolean hasTextContent(Node child) {
97          return child.getNodeType() != Node.COMMENT_NODE &&
98              child.getNodeType() != Node.PROCESSING_INSTRUCTION_NODE ;
99  //          &&
100 //            (child.getNodeType() != Node.TEXT_NODE );
101 //          ||
102 //             ((TextImpl) child).isIgnorableWhitespace() == false);
103     }
104 
105 // Stolen from Xerces 2.5.0 code - need to replace java 1.5 getTextContent method
106     void getTextContent(Node anode, StringBuffer buf)
107     {
108         Node child = anode.getFirstChild();
109         while (child != null)
110         {
111             if (hasTextContent(child))
112             {
113                 buf.append(child.getNodeValue());
114             }
115             child = child.getNextSibling();
116         }
117     }
118 
119 // Stolen from Xerces 2.5.0 code - need to replace java 1.5 getTextContent method
120     private String getTextContent(Node anode) //throws DOMException
121     {
122         Node child = anode.getFirstChild();
123         if (child != null)
124         {
125             Node next = child.getNextSibling();
126             if (next == null)
127             {
128                 return hasTextContent(child) ? child.getNodeValue() : "";
129             }
130             StringBuffer buf = new StringBuffer();
131             getTextContent(anode, buf);
132             return buf.toString();
133         }
134         return "";
135     }
136 
137   private String doNode(Node parent, String nodeName)
138   {
139     StringBuffer temp = new StringBuffer();
140     Node[] nodes = getNodesNamed(parent, nodeName);
141     for (int i = 0; i < nodes.length; i++)
142     {
143 // Java 1.5 library function
144 //      temp += nodes[i].getTextContent();
145       temp.append(getTextContent(nodes[i]));
146     }
147     return temp.toString();
148   }
149 
150   public ComponentDef(Node componentNode)
151   {
152     Map<String, String> attributes = getAttributeMap(componentNode);
153     name = attributes.get("name");
154     iconClass = attributes.get("iconClass");
155     description = attributes.get("desc");
156 // Java 1.5 library function.
157 //    isContainer = Boolean.parseBoolean(attributes.get("container"));
158     String str = attributes.get("container");
159     if ( str != null )
160     {
161       isContainer = ( str.compareToIgnoreCase("true") == 0 );
162     }
163 
164     imports = doNode(componentNode, "imports");
165     declarations = doNode(componentNode, "declarations");
166     configure = doNode(componentNode, "configure");
167     remove = doNode(componentNode, "remove");
168     add = doNode(componentNode, "add");
169     preview = doNode(componentNode, "preview");
170   }
171 
172   // KBR 12/31/05 Add a ctor for use by the "old-style" new button
173   public ComponentDef(String name, String imp, String decl, String add)
174   {
175     this.name = name;
176     this.imports = imp;
177     this.declarations = decl;
178     this.add = add;
179   }
180 
181 private static InputStream getCompFile()
182   {
183     // pull the components.xml file out of the root of the jar file
184     try
185     {
186       JarFile jf = new JarFile("formLayoutMakerx.jar");
187       JarEntry je = null;
188       Enumeration entries = jf.entries();
189       while(entries.hasMoreElements())
190       {
191           je = (JarEntry) entries.nextElement();
192           if (je.getName().equals("components.xml"))
193           {
194               return jf.getInputStream(je);
195           }
196       }
197     }
198     catch (IOException e)
199     {
200       return null;
201     }
202     return null;
203   }
204 
205   /*** Creates a new instance of Component Palette. All component configurations
206   are pulled out of components.xml
207   */
208   @SuppressWarnings("unchecked")
209   public static List<ComponentDef> createComponentDefs()
210   {
211     List<ComponentDef> components = new ArrayList<ComponentDef>();
212     InputStream paletteStream = ComponentDef.class.getResourceAsStream("components.xml");
213     if ( paletteStream == null )
214       paletteStream = getCompFile();
215     if ( paletteStream == null )
216       return components;
217 
218     Document dataDocument = null;
219 
220     try
221     {
222       DocumentBuilder documentBuilder = DocumentBuilderFactory.newInstance()
223           .newDocumentBuilder();
224       dataDocument = documentBuilder.parse(paletteStream);
225       Node paletteNode = dataDocument.getDocumentElement();
226       Node[] componentNodes = getNodesNamed(paletteNode, "component");
227 
228       for (int index = 0; index < componentNodes.length; index++)
229       {
230         Node componentNode = componentNodes[index];
231         components.add(new ComponentDef(componentNode));
232       }
233     }
234     catch (Exception e)
235     {
236       throw new RuntimeException("Unable to create DocumentBuilder", e);
237     }
238 
239     Collections.sort(components);
240     return components;
241   }
242 
243   private static Map<String, String> getAttributeMap(Node node)
244   {
245 
246     Map<String, String> attributeMap = new HashMap<String, String>();
247 
248     NamedNodeMap attributes = node.getAttributes();
249     if (attributes != null)
250     {
251       for (int index = 0; index < attributes.getLength(); index++)
252       {
253         Node attribute = attributes.item(index);
254         attributeMap.put(attribute.getNodeName(), attribute.getNodeValue());
255       }
256     }
257 
258     return attributeMap;
259   }
260 
261   private static Node[] getNodesNamed(Node parent, String nodeName)
262   {
263     NodeList children = parent.getChildNodes();
264     List<Node> childList = new ArrayList<Node>();
265     for (int i = 0; i < children.getLength(); i++)
266     {
267       String childname = children.item(i).getNodeName();
268       if ((childname != null) && nodeName.equals(childname))
269       {
270         childList.add(children.item(i));
271       }
272     }
273     Node[] result = new Node[childList.size()];
274     return (Node[]) childList.toArray(result);
275   }
276 
277   public String getConfigure(String name)
278   {
279     return configure.replaceAll("//$//{name//}", name);
280   }
281 
282   public String getImports(String name)
283   {
284     return imports.replaceAll("//$//{name//}", name);
285   }
286 
287   public String getDeclarations(String name)
288   {
289     return declarations.replaceAll("//$//{name//}", name);
290   }
291 
292   public String getAdd(String name)
293   {
294     return add.replaceAll("//$//{name//}", name);
295   }
296 
297   /*** When dragging from the palette we need a clone rather than modify
298       the original.
299   */
300   public ComponentDef clone()
301   {
302     ComponentDef newone = new ComponentDef();
303     newone.name = name;
304     newone.iconClass = iconClass;
305     newone.declarations = declarations;
306     newone.configure = configure;
307     newone.add = add;
308     newone.imports = imports;
309     newone.preview = preview;
310     newone.isContainer = isContainer;
311     return newone;
312   }
313 
314   /*** Make it sortable on name so the palette is ordered.
315   */
316   public int compareTo(Object o)
317   {
318     return name.compareTo(((ComponentDef)o).name);
319   }
320 
321   public static void main(String[] args)
322   {
323     List<ComponentDef> components = ComponentDef.createComponentDefs();
324     System.out.println(components);
325   }
326 }