1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
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
96 final boolean hasTextContent(Node child) {
97 return child.getNodeType() != Node.COMMENT_NODE &&
98 child.getNodeType() != Node.PROCESSING_INSTRUCTION_NODE ;
99
100
101
102
103 }
104
105
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
120 private String getTextContent(Node anode)
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
144
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
157
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
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
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 }