Source Code Cross Referenced for JGraphEditorModel.java in  » Graphic-Library » jgraphpad » com » jgraph » editor » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Graphic Library » jgraphpad » com.jgraph.editor 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /* 
002:         * $Id: JGraphEditorModel.java,v 1.6 2007/07/27 14:15:59 gaudenz Exp $
003:         * Copyright (c) 2001-2005, Gaudenz Alder
004:         * 
005:         * All rights reserved.
006:         * 
007:         * See LICENSE file for license details. If you are unable to locate
008:         * this file please contact info (at) jgraph (dot) com.
009:         */
010:        package com.jgraph.editor;
011:
012:        import java.beans.BeanInfo;
013:        import java.beans.DefaultPersistenceDelegate;
014:        import java.beans.Encoder;
015:        import java.beans.ExceptionListener;
016:        import java.beans.Expression;
017:        import java.beans.IntrospectionException;
018:        import java.beans.Introspector;
019:        import java.beans.PersistenceDelegate;
020:        import java.beans.PropertyDescriptor;
021:        import java.beans.XMLDecoder;
022:        import java.beans.XMLEncoder;
023:        import java.io.BufferedInputStream;
024:        import java.io.FileNotFoundException;
025:        import java.io.IOException;
026:        import java.io.InputStream;
027:        import java.io.OutputStream;
028:        import java.net.MalformedURLException;
029:        import java.util.ArrayList;
030:        import java.util.Enumeration;
031:        import java.util.Hashtable;
032:        import java.util.Iterator;
033:        import java.util.LinkedList;
034:        import java.util.List;
035:        import java.util.Map;
036:        import java.util.zip.GZIPInputStream;
037:        import java.util.zip.GZIPOutputStream;
038:
039:        import javax.swing.event.TreeModelEvent;
040:        import javax.swing.event.TreeModelListener;
041:        import javax.swing.tree.DefaultMutableTreeNode;
042:        import javax.swing.tree.DefaultTreeModel;
043:        import javax.swing.tree.MutableTreeNode;
044:        import javax.swing.tree.TreeNode;
045:        import javax.swing.tree.TreePath;
046:
047:        import org.jgraph.event.GraphLayoutCacheEvent;
048:        import org.jgraph.event.GraphLayoutCacheListener;
049:        import org.jgraph.event.GraphModelEvent;
050:        import org.jgraph.event.GraphModelListener;
051:        import org.jgraph.graph.DefaultEdge;
052:        import org.jgraph.graph.DefaultGraphModel;
053:        import org.jgraph.graph.EdgeView;
054:        import org.jgraph.graph.GraphConstants;
055:        import org.jgraph.graph.GraphLayoutCache;
056:        import org.jgraph.graph.PortView;
057:        import org.jgraph.graph.VertexView;
058:
059:        import com.jgraph.JGraphpad;
060:
061:        /**
062:         * Default document model for JGraph editors. This class is in charge of
063:         * preparing the bean info classes and has a map of persistence delegate for XML
064:         * encoding. You should use the writeObject and readObject method of this class
065:         * for file I/O to properly use the registered peristence delegates. <br>
066:         * Note: The API refers to the children of the {@link #rootNode}as roots.
067:         */
068:        public class JGraphEditorModel extends DefaultTreeModel {
069:
070:            /**
071:             * Prepares class bean infos for XML encoding. Note: To encode cell views
072:             * they must have an empty constructor and all fields (except cell and
073:             * attributes) must be marked transient in the BeanInfo. To do this for a
074:             * new cell view, use {@link #makeCellViewFieldsTransient(Class)}.
075:             */
076:            static {
077:                makeCellViewFieldsTransient(PortView.class);
078:                makeCellViewFieldsTransient(VertexView.class);
079:                makeCellViewFieldsTransient(EdgeView.class);
080:            }
081:
082:            /**
083:             * Holds the (class, persistence delegate) pairs.
084:             */
085:            protected Map persistenceDelegates = new Hashtable();
086:
087:            /**
088:             * Reference to the mutable root node.
089:             */
090:            protected DefaultMutableTreeNode rootNode;
091:
092:            /**
093:             * Constructs a new JGraph editor model adding persistence delegates for the
094:             * DefaultGraphModel, GraphLayoutCache and DefaultEdge.DefaultRouting
095:             * classes. This also adds a tree model listener to this model to update the
096:             * modified state of parent files for child changes.
097:             */
098:            public JGraphEditorModel() {
099:                super (new DefaultMutableTreeNode());
100:                rootNode = (DefaultMutableTreeNode) getRoot();
101:
102:                // Adds a listener to update parent file states
103:                // on child changes.
104:                addTreeModelListener(new TreeModelListener() {
105:
106:                    public void treeNodesChanged(TreeModelEvent e) {
107:                        Object[] children = e.getChildren();
108:                        for (int i = 0; i < children.length; i++) {
109:                            JGraphEditorFile file = getParentFile((TreeNode) children[i]);
110:
111:                            if (JGraphpad.INNER_LIBRARIES
112:                                    && file.getParent() instanceof  JGraphEditorFile) {
113:                                file = (JGraphEditorFile) file.getParent();
114:                            }
115:
116:                            if (file != children[i])
117:                                setModified(file, true);
118:                        }
119:                    }
120:
121:                    public void treeNodesInserted(TreeModelEvent e) {
122:                        Object[] children = e.getChildren();
123:                        for (int i = 0; i < children.length; i++) {
124:                            JGraphEditorFile file = getParentFile((TreeNode) children[i]);
125:
126:                            if (JGraphpad.INNER_LIBRARIES
127:                                    && file.getParent() instanceof  JGraphEditorFile) {
128:                                file = (JGraphEditorFile) file.getParent();
129:                            }
130:
131:                            if (file != children[i])
132:                                setModified(file, true);
133:                        }
134:                    }
135:
136:                    public void treeNodesRemoved(TreeModelEvent e) { // empty
137:                    }
138:
139:                    public void treeStructureChanged(TreeModelEvent e) { // empty
140:                    }
141:
142:                });
143:
144:                // Adds default persistence delegates
145:                addPersistenceDelegate(DefaultGraphModel.class,
146:                        new DefaultPersistenceDelegate(new String[] { "roots",
147:                                "attributes" }));
148:                addPersistenceDelegate(GraphLayoutCache.class,
149:                        new DefaultPersistenceDelegate(new String[] { "model",
150:                                "factory", "cellViews", "hiddenCellViews",
151:                                "partial" }));
152:
153:                // DefaultEdge.DefaultRouting has a shared instance which may
154:                // be retrieved using GraphConstants.getROUTING_SIMPLE().
155:                addPersistenceDelegate(DefaultEdge.DefaultRouting.class,
156:                        new PersistenceDelegate() {
157:                            protected Expression instantiate(
158:                                    Object oldInstance, Encoder out) {
159:                                return new Expression(oldInstance,
160:                                        GraphConstants.class,
161:                                        "getROUTING_SIMPLE", null);
162:                            }
163:                        });
164:
165:                addPersistenceDelegate(DefaultEdge.LoopRouting.class,
166:                        new PersistenceDelegate() {
167:                            protected Expression instantiate(
168:                                    Object oldInstance, Encoder out) {
169:                                return new Expression(oldInstance,
170:                                        GraphConstants.class,
171:                                        "getROUTING_DEFAULT", null);
172:                            }
173:                        });
174:            }
175:
176:            /**
177:             * Returns the first generation of childs, aka roots. This usually returns
178:             * the documents and repositories, eg files that are currently open.
179:             * 
180:             * @return Returns the children of {@link #rootNode}.
181:             */
182:            public Enumeration roots() {
183:                return rootNode.children();
184:            }
185:
186:            /**
187:             * Associates the specified persistence delegate with <code>clazz</code>
188:             * for XML encoding.
189:             * 
190:             * @param clazz
191:             *            The class to associate the delegate with.
192:             * @return Returns the previous delegate for <code>clazz</code>.
193:             */
194:            public Object addPersistenceDelegate(Class clazz,
195:                    PersistenceDelegate delegate) {
196:                if (delegate != null)
197:                    return persistenceDelegates.put(clazz, delegate);
198:                return null;
199:            }
200:
201:            /**
202:             * Returns the associated persistence delegate for <code>clazz</code> or
203:             * <code>null</code> if no association exists.
204:             * 
205:             * @param clazz
206:             *            The clazz to return the delegate for.
207:             * @return Returns the persistence delegate for <code>clazz</code> or
208:             *         <code>null</code>.
209:             */
210:            public PersistenceDelegate getPersistenceDelegate(Class clazz) {
211:                if (clazz != null)
212:                    return (PersistenceDelegate) persistenceDelegates
213:                            .get(clazz);
214:                return null;
215:            }
216:
217:            /**
218:             * Adds the specified root as a child to {@link #rootNode}. Calls
219:             * {@link #installListeners(TreeNode)}on the node.
220:             * 
221:             * @param node
222:             *            The node to add to {@link #rootNode}.
223:             * @return Returns the node that has been added.
224:             */
225:            public MutableTreeNode addRoot(MutableTreeNode node) {
226:                insertNodeInto(node, rootNode, getChildCount(getRoot()));
227:                installListeners(node);
228:                return node;
229:            }
230:
231:            /**
232:             * Adds the specified child to <code>parent</code>. Calls
233:             * {@link #installListeners(TreeNode)}on the child.
234:             * 
235:             * @param child
236:             *            The node to add to <code>parent</code>.
237:             * @param parent
238:             *            The parent to add <code>child</code> to.
239:             * @return Returns the child that has been added.
240:             */
241:            public MutableTreeNode addChild(MutableTreeNode child,
242:                    MutableTreeNode parent) {
243:                insertNodeInto(child, parent, getChildCount(parent));
244:                installListeners(child);
245:                return child;
246:            }
247:
248:            /**
249:             * Reads the specified URI and adds it as a root.
250:             * 
251:             * @param uri
252:             *            The URI to read the object from.
253:             * @return Returns the object stat was added.
254:             */
255:            public Object addFile(String uri) throws MalformedURLException,
256:                    IOException {
257:                if (uri != null) {
258:                    Object file = getFileByFilename(uri);
259:                    if (file == null) {
260:                        InputStream in = getInputStream(uri);
261:                        file = readObject(in);
262:                        in.close();
263:                        if (file instanceof  JGraphEditorFile) {
264:                            ((JGraphEditorFile) file).setFilename(uri);
265:                            addRoot((JGraphEditorFile) file);
266:                        }
267:                        return file;
268:                    }
269:                }
270:                return null;
271:            }
272:
273:            /**
274:             * Hook for subclassers to install the required listeners in new tree nodes.
275:             * This is invoked recursively for tree nodes and calls
276:             * {@link #installDiagramListeners(JGraphEditorDiagram)}on all diagrams
277:             * that are found along the invocation chain.
278:             * 
279:             * @param node
280:             *            The node to scan for diagrams.
281:             */
282:            protected void installListeners(TreeNode node) {
283:                if (node instanceof  TreeNode) {
284:                    for (int i = 0; i < getChildCount(node); i++) {
285:                        Object child = getChild(node, i);
286:                        if (child instanceof  TreeNode)
287:                            installListeners((TreeNode) child);
288:                    }
289:                }
290:                if (node instanceof  JGraphEditorDiagram) {
291:                    installDiagramListeners((JGraphEditorDiagram) node);
292:                }
293:            }
294:
295:            /**
296:             * Installs the listeners required to update the modified state of the
297:             * parent file node to <code>diagram</code>. This implementation adds a
298:             * graph layout cache listener and a graph model listener.
299:             * 
300:             * @param diagram
301:             *            The diagram to install the listeners to.
302:             */
303:            protected void installDiagramListeners(
304:                    final JGraphEditorDiagram diagram) {
305:                diagram.getGraphLayoutCache().addGraphLayoutCacheListener(
306:                        new GraphLayoutCacheListener() {
307:
308:                            public void graphLayoutCacheChanged(
309:                                    GraphLayoutCacheEvent e) {
310:                                JGraphEditorFile file = getParentFile(diagram);
311:                                if (JGraphpad.INNER_LIBRARIES
312:                                        && file.getParent() instanceof  JGraphEditorFile) {
313:                                    file = (JGraphEditorFile) file.getParent();
314:                                }
315:                                setModified(file, true);
316:                            }
317:
318:                        });
319:                diagram.getGraphLayoutCache().getModel().addGraphModelListener(
320:                        new GraphModelListener() {
321:
322:                            public void graphChanged(GraphModelEvent e) {
323:                                JGraphEditorFile file = getParentFile(diagram);
324:                                if (JGraphpad.INNER_LIBRARIES
325:                                        && file.getParent() instanceof  JGraphEditorFile) {
326:                                    file = (JGraphEditorFile) file.getParent();
327:                                }
328:                                setModified(file, true);
329:                            }
330:                        });
331:            }
332:
333:            /**
334:             * Sets the user object of the specified node and dispatches a notification
335:             * event.
336:             * 
337:             * @param node
338:             *            The node to change the user object for.
339:             * @param userObject
340:             *            The new user object.
341:             */
342:            public void setUserObject(TreeNode node, Object userObject) {
343:                TreePath path = new TreePath(getPathToRoot(node));
344:                valueForPathChanged(path, userObject);
345:            }
346:
347:            /**
348:             * Sets the filename of the specified file and dispatches a notification
349:             * event.
350:             * 
351:             * @param file
352:             *            The file to change the filename for.
353:             * @param filename
354:             *            The new filename.
355:             */
356:            public void setFilename(JGraphEditorFile file, String filename) {
357:                file.setFilename(filename);
358:                nodeChanged(file);
359:            }
360:
361:            /**
362:             * Sets the name of the specified diagram and dispatches a notification
363:             * event.
364:             * 
365:             * @param diagram
366:             *            The diagram to change the name for.
367:             * @param name
368:             *            The new name.
369:             */
370:            public void setName(JGraphEditorDiagram diagram, String name) {
371:                diagram.setName(name);
372:                nodeChanged(diagram);
373:            }
374:
375:            /**
376:             * Sets the modified state of the specified file and dispatches a
377:             * notification event.
378:             * 
379:             * @param file
380:             *            The file to change the modified state for.
381:             * @param modified
382:             *            The new modified state.
383:             */
384:            public void setModified(JGraphEditorFile file, boolean modified) {
385:                if (file != null) {
386:                    file.setModified(modified);
387:                    nodeChanged(file);
388:                }
389:            }
390:
391:            /**
392:             * Returns the file for the specified filename if it is in the model or
393:             * <code>null</code> if no such file exists.
394:             * 
395:             * @param filename
396:             *            The filename to return the file for.
397:             * @return Returns the file for <code>filename</code> or <code>null</code>.
398:             */
399:            public JGraphEditorFile getFileByFilename(String filename) {
400:                int childCount = getChildCount(rootNode);
401:                for (int i = 0; i < childCount; i++) {
402:                    Object child = getChild(rootNode, i);
403:                    if (child instanceof  JGraphEditorFile) {
404:                        JGraphEditorFile file = (JGraphEditorFile) child;
405:                        if (file.getFilename() != null
406:                                && file.getFilename().equals(filename)) {
407:                            return file;
408:                        }
409:                    }
410:                }
411:                return null;
412:            }
413:
414:            /**
415:             * Writes the specified object to the output stream using an xml encoder
416:             * which was configured using {@link #configureEncoder(XMLEncoder)}. The
417:             * exceptions that are thrown during encoding are caught by a local handler
418:             * and passed to the caller as a RuntimeException with description of the
419:             * encoding problems. <br>
420:             * Note: You should use this method as a global hook to write all XML files.
421:             * 
422:             * @param object
423:             *            The object to be written.
424:             * @param out
425:             *            The output strem to write to.
426:             * 
427:             * @throws RuntimeException
428:             *             If there are problems during encoding.
429:             */
430:            public void writeObject(Object object, OutputStream out) {
431:                final List problems = new LinkedList();
432:                if (object != null) {
433:                    XMLEncoder enc = new XMLEncoder(out);
434:                    enc.setExceptionListener(new ExceptionListener() {
435:                        public void exceptionThrown(Exception e) {
436:                            // Uncomment this line for debugging
437:                            // XML encoding:
438:                            e.printStackTrace();
439:                            problems.add(e);
440:                        }
441:                    });
442:                    configureEncoder(enc);
443:                    enc.writeObject(object);
444:                    enc.close();
445:                }
446:                if (!problems.isEmpty())
447:                    throw new RuntimeException(problems.size()
448:                            + " errors while writing " + object + " ("
449:                            + problems.get(0) + ")");
450:            }
451:
452:            /**
453:             * Hook for subclassers to configure a new XML encoder for writing an
454:             * object. This implementation sets all registered persistence delegates and
455:             * installs default mappings for classes (eg. it assigns the list
456:             * persistence delegates to array lists).
457:             * 
458:             * @param enc
459:             *            The encoder to be configured.
460:             */
461:            protected void configureEncoder(XMLEncoder enc) {
462:                Iterator it = persistenceDelegates.entrySet().iterator();
463:                while (it.hasNext()) {
464:                    Map.Entry entry = (Map.Entry) it.next();
465:                    enc.setPersistenceDelegate((Class) entry.getKey(),
466:                            (PersistenceDelegate) entry.getValue());
467:                }
468:                enc.setPersistenceDelegate(ArrayList.class, enc
469:                        .getPersistenceDelegate(List.class));
470:            }
471:
472:            /**
473:             * Hook for subclassers to create an input stream for the specified URI.
474:             * This implementation creates an input stream using
475:             * {@link JGraphEditorResources#getInputStream(String)} and wraps it in a
476:             * {@link GZIPInputStream} if the URI ends with <code>.gz</code>.
477:             * 
478:             * @param uri
479:             *            The URI to return the input stream for.
480:             * @return Return an input stream for the specified URI.
481:             */
482:            public InputStream getInputStream(String uri)
483:                    throws MalformedURLException, FileNotFoundException,
484:                    IOException {
485:                InputStream in = JGraphEditorResources.getInputStream(uri);
486:                if (uri.toLowerCase().endsWith(".gz"))
487:                    in = new GZIPInputStream(in);
488:                return new BufferedInputStream(in);
489:            }
490:
491:            /**
492:             * Hook for subclassers to create an output stream for the specified URI.
493:             * This implementation creates an output stream using
494:             * {@link JGraphEditorResources#getOutputStream(String)} and wraps it in a
495:             * {@link java.util.zip.GZIPOutputStream} if the URI ends with
496:             * <code>.gz</code>.
497:             * 
498:             * @param uri
499:             *            The URI to return the output stream for.
500:             * @return Returns an output stream for the specified URI.
501:             */
502:            public OutputStream getOutputStream(String uri) throws IOException {
503:                OutputStream out = JGraphEditorResources.getOutputStream(uri);
504:                if (uri.toLowerCase().endsWith(".gz"))
505:                    out = new GZIPOutputStream(out);
506:                return out;
507:            }
508:
509:            /**
510:             * Returns a new object from the specified stream using a new XML decoder.
511:             * This method does nothing special. Subclassers can override this method if
512:             * they need to do anything special with opened files. <br>
513:             * Note: You should use this method as a global hook to read all XML files.
514:             * 
515:             * @return Returns a new object from the specified stream.
516:             */
517:            public Object readObject(InputStream in) {
518:                XMLDecoder dec = new XMLDecoder(in);
519:                if (dec != null) {
520:                    Object obj = dec.readObject();
521:                    dec.close();
522:                    return obj;
523:                }
524:                return null;
525:            }
526:
527:            /**
528:             * Makes the specified field transient in the bean info of
529:             * <code>clazz</code>.
530:             * 
531:             * @param clazz
532:             *            The class whos field should be made transient.
533:             * @param field
534:             *            The name of the field that should be made transient.
535:             */
536:            public static void makeTransient(Class clazz, String field) {
537:                try {
538:                    BeanInfo info = Introspector.getBeanInfo(clazz);
539:                    PropertyDescriptor[] propertyDescriptors = info
540:                            .getPropertyDescriptors();
541:                    for (int i = 0; i < propertyDescriptors.length; ++i) {
542:                        PropertyDescriptor pd = propertyDescriptors[i];
543:                        if (pd.getName().equals(field)) {
544:                            pd.setValue("transient", Boolean.TRUE);
545:                        }
546:                    }
547:                } catch (IntrospectionException e) {
548:                    // ignore
549:                }
550:            }
551:
552:            /**
553:             * Makes all fields but <code>cell</code> and <code>attributes</code>
554:             * transient in the bean info of <code>clazz</code>.
555:             * 
556:             * @param clazz
557:             *            The cell view class who fields should be made transient.
558:             */
559:            public static void makeCellViewFieldsTransient(Class clazz) {
560:                try {
561:                    BeanInfo info = Introspector.getBeanInfo(clazz);
562:                    PropertyDescriptor[] propertyDescriptors = info
563:                            .getPropertyDescriptors();
564:                    for (int i = 0; i < propertyDescriptors.length; ++i) {
565:                        PropertyDescriptor pd = propertyDescriptors[i];
566:                        if (!pd.getName().equals("cell")
567:                                && !pd.getName().equals("attributes")) {
568:                            pd.setValue("transient", Boolean.TRUE);
569:                        }
570:                    }
571:                } catch (IntrospectionException e) {
572:                    e.printStackTrace();
573:                }
574:            }
575:
576:            /**
577:             * Returns the parent file for <code>node</code> or the node itself, if it
578:             * is a file. This method returns <code>null</code> if no parent file is
579:             * found for <code>node</code>.
580:             * 
581:             * @param node
582:             *            The node to find the parent file for.
583:             * @return Returns the parent file for node, the node itself or
584:             *         <code>null</code>.
585:             */
586:            public static JGraphEditorFile getParentFile(TreeNode node) {
587:                while (node != null) {
588:                    if (node instanceof  JGraphEditorFile)
589:                        return (JGraphEditorFile) node;
590:                    node = node.getParent();
591:                }
592:                return null;
593:            }
594:
595:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.