openjpa-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ppod...@apache.org
Subject svn commit: r944083 [1/4] - in /openjpa/trunk/openjpa-examples/openbooks/src: ./ main/ main/java/ main/java/jpa/ main/java/jpa/tools/ main/java/jpa/tools/swing/ main/java/openbook/ main/java/openbook/client/ main/java/openbook/domain/ main/java/openboo...
Date Fri, 14 May 2010 02:14:32 GMT
Author: ppoddar
Date: Fri May 14 02:14:30 2010
New Revision: 944083

URL: http://svn.apache.org/viewvc?rev=944083&view=rev
Log:
Adding initial files

Added:
    openjpa/trunk/openjpa-examples/openbooks/src/
    openjpa/trunk/openjpa-examples/openbooks/src/main/
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/AttributeLegendView.java   (with props)
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/AttributeView.java   (with props)
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/ConfigurationViewer.java   (with props)
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/EntityDataModel.java   (with props)
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/EntityTable.java   (with props)
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/EntityTableView.java   (with props)
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/EntityTypeView.java   (with props)
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/ErrorDialog.java   (with props)
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/FileScanner.java   (with props)
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/Finder.java   (with props)
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/GraphicOutputStream.java   (with props)
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/ImageBorder.java   (with props)
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/InstanceDataModel.java   (with props)
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/InstanceView.java   (with props)
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/Maze.java   (with props)
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/MetamodelHelper.java   (with props)
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/MetamodelView.java   (with props)
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/PathFinder.java   (with props)
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/PowerPointViewer.java   (with props)
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/PreparedQueryViewer.java   (with props)
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/QueryDecorator.java   (with props)
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/QueryStatisticsModel.java   (with props)
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/SQLLogger.java   (with props)
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/ScrollingTextPane.java   (with props)
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/SourceCodeViewer.java   (with props)
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/StatusBar.java   (with props)
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/SwingHelper.java   (with props)
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/TextStyles.java   (with props)
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/package.html   (with props)
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/client/
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/client/BuyBookPage.java   (with props)
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/client/DeliveryPage.java   (with props)
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/client/Demo.java   (with props)
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/client/Images.java   (with props)
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/client/SQLLogger.java   (with props)
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/client/SupplyPage.java   (with props)
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/Author.java   (with props)
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/Author_.java   (with props)
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/Book.java   (with props)
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/Book_.java   (with props)
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/Customer.java   (with props)
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/Customer_.java   (with props)
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/Inventory.java   (with props)
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/Inventory_.java   (with props)
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/LineItem.java   (with props)
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/LineItem_.java   (with props)
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/PurchaseOrder.java   (with props)
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/PurchaseOrder_.java   (with props)
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/Range.java   (with props)
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/ShoppingCart.java   (with props)
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/server/
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/server/OpenBookService.java   (with props)
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/server/OpenBookServiceImpl.java   (with props)
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/server/PersistenceService.java   (with props)
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/server/QueryDecorator.java   (with props)
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/server/QueryParameterBinder.java   (with props)
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/server/ServiceFactory.java   (with props)
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/util/
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/util/PropertyHelper.java   (with props)
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/util/Randomizer.java   (with props)
    openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/util/package.html   (with props)
    openjpa/trunk/openjpa-examples/openbooks/src/main/resources/
    openjpa/trunk/openjpa-examples/openbooks/src/main/resources/source/
    openjpa/trunk/openjpa-examples/openbooks/src/main/resources/source/jpa/
    openjpa/trunk/openjpa-examples/openbooks/src/main/resources/source/jpa/tools/
    openjpa/trunk/openjpa-examples/openbooks/src/main/resources/source/jpa/tools/swing/
    openjpa/trunk/openjpa-examples/openbooks/src/main/resources/source/jpa/tools/swing/AttributeLegendView.html

Added: openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/AttributeLegendView.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/AttributeLegendView.java?rev=944083&view=auto
==============================================================================
--- openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/AttributeLegendView.java (added)
+++ openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/AttributeLegendView.java Fri May 14 02:14:30 2010
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2010-2012 Pinaki Poddar
+ *
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+*/
+package jpa.tools.swing;
+
+import java.awt.Color;
+import java.awt.GridLayout;
+import java.awt.image.BufferedImage;
+
+import javax.persistence.metamodel.Attribute;
+import javax.swing.BorderFactory;
+import javax.swing.ImageIcon;
+import javax.swing.JComponent;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+
+/**
+ * Displays color codes of each attribute type.
+ * 
+ * @author Pinaki Poddar
+ *
+ */
+@SuppressWarnings("serial")
+public class AttributeLegendView extends JPanel {
+    
+    public AttributeLegendView() {
+        super(true);
+        setBorder(BorderFactory.createTitledBorder("Attribute Legends"));
+        setLayout(new GridLayout(0,3));
+        add(createColoredLabel("IDENTITY", Color.RED));
+        add(createColoredLabel("VERSION", Color.DARK_GRAY));
+        for (Attribute.PersistentAttributeType type : Attribute.PersistentAttributeType.values()) {
+          add(createColoredLabel(type.toString().replace('_', ' '), MetamodelHelper.getColor(type)));
+      }        
+    }
+    
+    JComponent createColoredLabel(String text, Color c) {
+        int width  = 40;
+        int height = 20;
+        BufferedImage bimage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); 
+        for (int i = 0; i < width; i++)
+            for (int j = 0; j < height; j++)
+                bimage.setRGB(i, j, c.getRGB());
+        JLabel label = new JLabel(text, new ImageIcon(bimage), JLabel.LEADING);
+        return label;
+    }
+
+}

Propchange: openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/AttributeLegendView.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/AttributeView.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/AttributeView.java?rev=944083&view=auto
==============================================================================
--- openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/AttributeView.java (added)
+++ openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/AttributeView.java Fri May 14 02:14:30 2010
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2010-2012 Pinaki Poddar
+ *
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+*/
+package jpa.tools.swing;
+
+import java.awt.Color;
+
+import javax.persistence.metamodel.Attribute;
+import javax.swing.JLabel;
+
+/**
+ * View of a persistent attribute as a JLabel.
+ * 
+ * @author Pinaki Poddar
+ *
+ */
+@SuppressWarnings("serial")
+public class AttributeView extends JLabel {
+    private final Attribute<?,?> _attr;
+    
+    public AttributeView(Attribute<?,?> attr) {
+        _attr = attr;
+        Color color = MetamodelHelper.getColor(attr);
+        setForeground(color);
+        setText(MetamodelHelper.getDisplayName(attr));
+    }
+    
+    public Attribute<?,?> getAttribute() {
+        return _attr;
+    }
+}

Propchange: openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/AttributeView.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/ConfigurationViewer.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/ConfigurationViewer.java?rev=944083&view=auto
==============================================================================
--- openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/ConfigurationViewer.java (added)
+++ openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/ConfigurationViewer.java Fri May 14 02:14:30 2010
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2010-2012 Pinaki Poddar
+ *
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+*/
+package jpa.tools.swing;
+
+import java.awt.BorderLayout;
+import java.util.Arrays;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+
+import javax.swing.BorderFactory;
+import javax.swing.JPanel;
+import javax.swing.JScrollBar;
+import javax.swing.JScrollPane;
+import javax.swing.JTextPane;
+
+/**
+ * Displays Properties.
+ * 
+ * @author Pinaki Poddar
+ * 
+ */
+@SuppressWarnings("serial")
+public class ConfigurationViewer extends JTextPane {
+    private static final char SPACE = ' ';
+
+    public ConfigurationViewer(String title, Map<String, Object> config) {
+        super();
+        setBorder(BorderFactory.createTitledBorder(title));
+        TreeSet<String> sortedKeys = new TreeSet<String>(config.keySet());
+        int L = getMaxLength(sortedKeys);
+        for (String key : sortedKeys) {
+            setCaretPosition(getDocument().getLength());
+            setCharacterAttributes(TextStyles.KEYS, true);
+            replaceSelection(key + pad(L - key.length()) + ":");
+            setCaretPosition(getDocument().getLength());
+            setCharacterAttributes(TextStyles.VALUES, true);
+            replaceSelection(toString(config.get(key)) + "\r\n");
+        }
+    }
+    
+    String toString(Object value) {
+        if (value == null)
+            return "null";
+        if (value.getClass().isArray()) {
+            return Arrays.toString((Object[])value);
+        }
+        return value.toString();
+    }
+
+    private int getMaxLength(Set<String> keys) {
+        int len = 1;
+        for (String s : keys) {
+            len = Math.max(s.length(), len);
+        }
+        return len;
+    }
+
+    private String pad(int n) {
+        StringBuffer buf = new StringBuffer();
+        for (int i = 0; i < n; i++)
+            buf.append(SPACE);
+        return buf.toString();
+    }
+
+}

Propchange: openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/ConfigurationViewer.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/EntityDataModel.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/EntityDataModel.java?rev=944083&view=auto
==============================================================================
--- openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/EntityDataModel.java (added)
+++ openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/EntityDataModel.java Fri May 14 02:14:30 2010
@@ -0,0 +1,260 @@
+/*
+ * Copyright 2010-2012 Pinaki Poddar
+ *
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+*/
+package jpa.tools.swing;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import javax.persistence.metamodel.Attribute;
+import javax.persistence.metamodel.EntityType;
+import javax.persistence.metamodel.Metamodel;
+import javax.persistence.metamodel.PluralAttribute;
+import javax.persistence.metamodel.SingularAttribute;
+import javax.swing.table.AbstractTableModel;
+import javax.swing.table.TableModel;
+
+/**
+ * A data model for a tabular view of a list of persistent entities.
+ * The data supplied by this model can be filtered to display field values of
+ * basic type or single-valued or multi-valued relationships.  
+ * <br>
+ * The meta-information about the attributes of the entity are supplied by 
+ * newly defined {@link Metamodel meta-model API} of JPA 2.0 specification.
+ *  
+ * @author Pinaki Poddar
+ *
+ */
+@SuppressWarnings("serial")
+public class EntityDataModel<T> extends AbstractTableModel implements TableModel, Iterable<T> {
+    /**
+     * Constant designates to include non-relation fields.
+     */
+    public static int BASIC_ATTR       = 1 << 0;
+    /**
+     * Constant designates to include single-valued relation fields.
+     */
+    public static int ASSOCIATION_ATTR = 1 << 1;
+    /**
+     * Constant designates to include multi-valued relation fields.
+     */
+    public static int PLURAL_ATTR      = 1 << 2;
+    /**
+     * Constant designates to include all fields.
+     */
+    public static int ALL_ATTR         = BASIC_ATTR | ASSOCIATION_ATTR | PLURAL_ATTR;
+    /**
+     * Constant designates to show a row count field at the first column.
+     */
+    public static int ROW_COUNT        = 1 << 3;
+
+    private List<String>   columnNames;
+    private List<Class<?>> columnClasses;
+    private List<Method>   methods;
+    private List<T>        data;
+    private List<Attribute<? super T,?>> attributes; 
+    private static Object[] EMPTY_ARGS = null;
+    private static Class<?>[] EMPTY_CLASSES = null;
+    
+    private boolean showsRowCount;
+    private boolean showsBasicAttr;
+    private boolean showsSingularAttr;
+    private boolean showsPluralAttr;
+    
+    /**
+     * Attributes of the entity are reordered with basic attributes, followed by singular
+     * association followed by the many-valued attributes.
+     *  
+     * @param cls
+     * @param data
+     * @param meta
+     */
+    public EntityDataModel(Class<T> cls, List<T> data, Metamodel meta, int styleBits) {
+        super();
+        this.data = data;
+        EntityType<T> entityType = meta.entity(cls);
+        
+        columnNames   = new ArrayList<String>();
+        columnClasses = new ArrayList<Class<?>>();
+        attributes    = new ArrayList<Attribute<? super T,?>>();
+        methods       = new ArrayList<Method>();
+        
+        showsRowCount     = (styleBits & ROW_COUNT) != 0;
+        showsBasicAttr    = (styleBits & BASIC_ATTR) != 0;
+        showsSingularAttr = (styleBits & ASSOCIATION_ATTR) != 0;
+        showsPluralAttr   = (styleBits & PLURAL_ATTR) != 0;
+        
+        Set<SingularAttribute<? super T, ?>> sAttrs = entityType.getSingularAttributes();
+        if (showsBasicAttr) {
+            for (SingularAttribute<? super T, ?> attr : sAttrs) {
+                if (!attr.isAssociation()) {
+                    attributes.add(attr);
+                }
+            }
+        }
+        if (showsSingularAttr) {
+            for (SingularAttribute<? super T, ?> attr : sAttrs) {
+                if (attr.isAssociation()) {
+                    attributes.add(attr);
+                }
+            }
+        }
+        if (showsPluralAttr) {
+            Set<PluralAttribute<? super T, ?, ?>> pAttrs = entityType.getPluralAttributes();
+            for (PluralAttribute<? super T, ?, ?> attr : pAttrs) {
+                attributes.add(attr);
+            }
+        }
+        Collections.sort(attributes, new MetamodelHelper.AttributeComparator());
+        for (Attribute<? super T, ?> attr : attributes) {
+            populate(cls, attr);
+        }
+        if (showsRowCount) {
+            columnNames.add(0,"Row");
+            columnClasses.add(0, Long.class);
+            attributes.add(0, null);
+            methods.add(0, null);
+        }
+    }
+    
+    private void populate(Class<T> cls, Attribute<?,?> attr) {
+        columnNames.add(attr.getName());
+        columnClasses.add(wrap(attr.getJavaType()));
+        methods.add(getMethod(cls, attr.getName()));
+    }
+
+    /**
+     * Gets the attribute at a given column index.
+     * Can be null for 0-th index if row count is being shown. 
+     */
+    public Attribute<?,?> getAttribute(int columnIndex) { 
+        return attributes.get(columnIndex);
+    }
+    
+    /**
+     * Gets the entity represented in the given row.
+     */
+    public T getRow(int row) {
+        return data.get(row);
+    }
+    
+    @Override
+    public Class<?> getColumnClass(int columnIndex) {
+        return columnClasses.get(columnIndex);
+    }
+
+    @Override
+    public int getColumnCount() {
+        return columnNames.size();
+    }
+
+    @Override
+    public String getColumnName(int columnIndex) {
+        return columnNames.get(columnIndex);
+    }
+
+    @Override
+    public int getRowCount() {
+        return data.size();
+    }
+
+    @Override
+    public Object getValueAt(int rowIndex, int columnIndex) {
+        Method method = methods.get(columnIndex);
+        if (method == null) {
+            return columnIndex == 0 && showsRowCount ? rowIndex+1 :  "?";
+        }
+        Object row = data.get(rowIndex);
+        Object val = getValueByReflection(rowIndex, row, columnIndex, method);
+        return val; 
+    }
+
+    @Override
+    public boolean isCellEditable(int rowIndex, int columnIndex) {
+        return false;
+    }
+
+    @Override
+    public void setValueAt(Object value, int rowIndex, int columnIndex) {
+        // should never be called
+    }
+
+    /**
+     * Gets the value by reflection.
+     * @param o
+     * @param p
+     * @return
+     */
+    Object getValueByReflection(int rowIndex, Object o, int columnIndex, Method m) {
+        if (o == null) {
+            System.err.println("Row " + rowIndex + " is null");
+            return null;
+        }
+        if (m == null) {
+            System.err.println("Column " + columnIndex + ":" + getColumnName(columnIndex) + " method is null");
+            return null;
+        }
+        try {
+            return m.invoke(o, EMPTY_ARGS);
+        } catch (Exception e) {
+            System.err.println("Can not extract value at [" + rowIndex + "," + columnIndex + "] due to " + e);
+            e.printStackTrace();
+        }
+        return null;
+    }
+    
+    Class<?> wrap(Class<?> c) {
+        if (c == null || c.isInterface() || c.isArray())
+            return Object.class;
+        if (c.isPrimitive()) {
+            if (c == boolean.class) return Boolean.class;
+            if (c == byte.class) return Byte.class;
+            if (c == char.class) return Character.class;
+            if (c == double.class) return Double.class;
+            if (c == float.class) return Float.class;
+            if (c == int.class) return Integer.class;
+            if (c == long.class) return Long.class;
+            if (c == short.class) return Short.class;
+        }
+        return c;
+    }
+    
+    private Method getMethod(Class<T> type, String p) {
+        try {
+            String getter = "get" + Character.toUpperCase(p.charAt(0))+p.substring(1);
+            return type.getMethod(getter, EMPTY_CLASSES);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return null;
+        
+    }
+    
+    public void updateData(List<T> newData) {
+        data = newData;
+        fireTableDataChanged();
+    }
+
+    @Override
+    public Iterator<T> iterator() {
+        return data.iterator();
+    }
+    
+}

Propchange: openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/EntityDataModel.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/EntityTable.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/EntityTable.java?rev=944083&view=auto
==============================================================================
--- openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/EntityTable.java (added)
+++ openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/EntityTable.java Fri May 14 02:14:30 2010
@@ -0,0 +1,207 @@
+/*
+ * Copyright 2010-2012 Pinaki Poddar
+ *
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+*/
+package jpa.tools.swing;
+
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.util.List;
+
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.PersistenceUnitUtil;
+import javax.persistence.metamodel.Attribute;
+import javax.swing.DefaultCellEditor;
+import javax.swing.JComboBox;
+import javax.swing.JLabel;
+import javax.swing.JTable;
+import javax.swing.ListSelectionModel;
+import javax.swing.table.DefaultTableCellRenderer;
+import javax.swing.table.TableCellEditor;
+import javax.swing.table.TableCellRenderer;
+import javax.swing.table.TableColumn;
+import javax.swing.table.TableModel;
+
+import org.apache.openjpa.enhance.PersistenceCapable;
+import org.apache.openjpa.enhance.StateManager;
+
+
+/**
+ * A specialized Swing table to display a list of persistent entity instances.
+ * The data for the table is supplied via a specialized {@linkplain EntityDataModel data model}
+ * that is supplied at construction.
+ * <br>
+ * The table view uses specialized cell renderer to display single-valued and multi-valued
+ * association.  
+ * 
+ * 
+ * @author Pinaki Poddar
+ *
+ */
+@SuppressWarnings("serial")
+public class EntityTable<T> extends JTable {
+    private InstanceCellRenderer instanceCellRenderer;
+    private CollectionCellRenderer collectionCellRenderer;
+    
+    public EntityTable(Class<T> cls, List<T> data, int styleBits, EntityManagerFactory unit) {
+        super();
+        instanceCellRenderer   = new InstanceCellRenderer(unit.getPersistenceUnitUtil());
+        collectionCellRenderer = new CollectionCellRenderer();
+        setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+        
+        setModel(new EntityDataModel<T>(cls, data,  unit.getMetamodel(), styleBits));
+        getModel().addTableModelListener(this);
+        initColumnSizes();
+        setFillsViewportHeight(true);
+    }
+    
+    
+    public InstanceCellRenderer getInstanceRenderer() {
+        return instanceCellRenderer;
+    }
+    
+    /**
+     * Gets the special renderer for single- and multi-valued association.
+     * Otherwise uses the super classes' renderer defined by the field type.    
+     */
+    public TableCellRenderer getCellRenderer(int row, int column) {
+        Attribute<?,?> attr = ((EntityDataModel)getModel()).getAttribute(column);
+        TableCellRenderer renderer = null;
+        if (attr == null) {
+            renderer = super.getCellRenderer(row, column);
+        } else if (attr.isAssociation()) {
+            renderer = instanceCellRenderer;
+        } else if (attr.isCollection()) {
+            renderer = collectionCellRenderer;
+        } else {
+            renderer = super.getCellRenderer(row, column);
+        }
+        if (renderer instanceof DefaultTableCellRenderer) {
+            ((DefaultTableCellRenderer)renderer).setHorizontalAlignment(JLabel.CENTER);
+        }
+        
+        return renderer;
+    }
+    
+    public TableCellEditor getCellEditor(int row, int column) {
+        Attribute<?,?> attr = ((EntityDataModel)getModel()).getAttribute(column);
+        if (attr == null)
+            return super.getCellEditor(row, column);
+        if (attr.isCollection())
+            return new DefaultCellEditor((JComboBox)getCellRenderer(row, column));
+        return super.getCellEditor(row, column);
+    }
+    
+    /**
+     * Picks good column sizes.
+     * If all column heads are wider than the column's cells'
+     * contents, then you can just use column.sizeWidthToFit().
+     */
+    private void initColumnSizes() {
+        TableModel model   = getModel();
+        TableColumn column = null;
+        Component comp     = null;
+        int headerWidth    = 0;
+        
+        TableCellRenderer headerRenderer =  getTableHeader().getDefaultRenderer();
+
+        for (int columnIndex = 0; columnIndex < model.getColumnCount(); columnIndex++) {
+            int cellWidth = 0;
+            column = getColumnModel().getColumn(columnIndex);
+
+            comp = headerRenderer.getTableCellRendererComponent(
+                                 null, column.getHeaderValue(),
+                                 false, false, 0, 0);
+            headerWidth = comp.getPreferredSize().width;
+            TableCellRenderer renderer = getCellRenderer(0, columnIndex);
+            int rowCount = Math.min(model.getRowCount(), 10);
+            for (int rowIndex = 0; rowIndex < rowCount; rowIndex++) {
+                Object value = model.getValueAt(rowIndex, columnIndex); 
+                comp = renderer.getTableCellRendererComponent(
+                                 this, value,
+                                 false, false, rowIndex, columnIndex);
+                cellWidth = Math.max(comp.getPreferredSize().width, cellWidth);
+            }
+            column.setPreferredWidth(Math.max(headerWidth, cellWidth));
+        }
+    }
+    
+    /**
+     * Renders the value of a persistent entity in a table column as the persistent identifier.
+     * The persistent identifier is extracted by the new {@link PersistenceUnitUtil utility} feature
+     * of JPA 2.0 API.
+     * 
+     * @author Pinaki Poddar
+     *
+     */
+    public class InstanceCellRenderer extends DefaultTableCellRenderer {
+        private final PersistenceUnitUtil util;
+        
+        public InstanceCellRenderer(PersistenceUnitUtil util) {
+            super();
+            this.util = util;
+        }
+        
+        /**
+         * Gets the stringified persistence identifier of the given instance.
+         * 
+         */
+        public String renderAsString(Object instance) {
+            if (instance == null) {
+                return "null";
+            }
+            Object id = util.getIdentifier(instance);
+            if (id != null)
+                return id.toString();
+            if (instance instanceof PersistenceCapable) {
+                PersistenceCapable pc = (PersistenceCapable)instance;
+                StateManager sm = pc.pcGetStateManager();
+                id = sm == null ? null : sm.fetchObjectId();
+            }
+            return id == null ? "null" : id.toString();
+        }
+
+        public void setValue(Object instance) {
+            setForeground(Color.BLUE);
+            setText(renderAsString(instance));
+        }
+
+    }
+
+    
+    /**
+     * Renders a many-valued attribute as simply three dots.
+     * 
+     * @author Pinaki Poddar
+     *
+     */
+    public class CollectionCellRenderer extends DefaultTableCellRenderer {
+        public CollectionCellRenderer() {
+            setPreferredSize(new Dimension(10,20));
+        }
+        @Override
+        public Component getTableCellRendererComponent(JTable table, Object value, 
+                boolean isSelected, boolean hasFocus, int row, int column) {
+            return super.getTableCellRendererComponent(table, value == null ? null : "...", 
+                    isSelected, hasFocus, row, column);
+        }
+
+    }
+
+
+
+    
+}

Propchange: openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/EntityTable.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/EntityTableView.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/EntityTableView.java?rev=944083&view=auto
==============================================================================
--- openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/EntityTableView.java (added)
+++ openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/EntityTableView.java Fri May 14 02:14:30 2010
@@ -0,0 +1,144 @@
+/*
+ * Copyright 2010-2012 Pinaki Poddar
+ *
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+*/
+package jpa.tools.swing;
+
+import java.awt.Color;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.metamodel.Attribute;
+import javax.persistence.metamodel.EntityType;
+import javax.persistence.metamodel.ManagedType;
+import javax.swing.BorderFactory;
+import javax.swing.BoxLayout;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTextArea;
+import javax.swing.ListSelectionModel;
+import javax.swing.border.Border;
+import javax.swing.border.TitledBorder;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+
+import jpa.tools.swing.EntityTable.InstanceCellRenderer;
+
+
+/**
+ * An entity table view consists of a JTable and optionally another table for many-valued associations.
+ *  
+ * @author Pinaki Poddar
+ *
+ */
+@SuppressWarnings("serial")
+public class EntityTableView<T> extends JPanel implements ListSelectionListener {
+    private EntityTable<T> _table;
+    private JTextArea _details;
+    
+    public EntityTableView(Class<T> cls, int styleBits, EntityManagerFactory unit) {
+        this(cls, (List<T>)Collections.EMPTY_LIST, styleBits, unit);
+    }
+    
+    public EntityTableView(Class<T> cls, List<T> data, int styleBits, EntityManagerFactory unit) {
+        super(true);
+        _table   = new EntityTable<T>(cls, data, styleBits, unit);
+        _table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+        
+        if ((styleBits & EntityDataModel.PLURAL_ATTR) != 0) {
+            _table.getSelectionModel().addListSelectionListener(this);
+            _details = new JTextArea("Click many-valued columns for display");
+            _details.setForeground(Color.LIGHT_GRAY);
+            _details.setBorder(BorderFactory.createTitledBorder("Many-valued association"));
+            _details.setEditable(false);
+        }
+        setBorder(BorderFactory.createTitledBorder(_table.getModel().getRowCount() + " " +
+                unit.getMetamodel().entity(cls).getName()));
+        
+        setLayout(new BoxLayout(this,BoxLayout.Y_AXIS));
+        add(new JScrollPane(_table, 
+                JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, 
+                JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS));
+        if (_details != null)
+            add(_details);
+    }
+    
+    public EntityTable<T> getTable() {
+        return _table;
+    }
+    
+    public EntityDataModel<T> getDataModel() {
+        return (EntityDataModel<T>)_table.getModel();
+    }
+    
+    public void updateTitle(String txt) {
+        Border border = getBorder();
+        if (border instanceof TitledBorder) {
+            ((TitledBorder)border).setTitle(txt);
+            repaint();
+        }
+    }
+    /**
+     * Notified when a cell in the table is selected.
+     * If the selected cell is a many-valued attribute then displays its details in the details pane.
+     */
+    @Override
+    public void valueChanged(ListSelectionEvent e) {
+        int row = _table.getSelectedRow();
+        if (row == -1)
+            return;
+        int col = _table.getSelectedColumn();
+        if (col == -1)
+            return;
+        EntityDataModel<?> model = (EntityDataModel<?>)_table.getModel();
+        Attribute<?,?> attr = model.getAttribute(col);
+        if (attr.isCollection()) {
+            Object val = model.getValueAt(row, col);
+            showDetails(attr, val);
+        }
+    }
+    
+    private void showDetails(Attribute<?,?> attr, Object val) {
+        _details.setText(null);
+        ManagedType<?> owner = attr.getDeclaringType();
+        String title = (owner instanceof EntityType) 
+                     ? ((EntityType<?>)owner).getName() + "." + attr.getName()
+                     : owner.getJavaType().getSimpleName() + "." + attr.getName(); 
+        TitledBorder border = (TitledBorder)_details.getBorder();
+        
+        if (val == null) {
+            border.setTitle(title + " (null)");
+        } else {
+            Collection<?> coll = (Collection<?>)val;
+            if (attr.getPersistentAttributeType() == Attribute.PersistentAttributeType.ELEMENT_COLLECTION) {
+                border.setTitle(title + " (" + coll.size() + " values)");
+                _details.setForeground(Color.BLACK);
+                for (Object e : coll) {
+                    _details.append(_table.getInstanceRenderer().renderAsString(e) + "\r\n");
+                    _details.append(e + "\r\n");
+                }
+            } else {
+                border.setTitle(title + " (" + coll.size() + " instances)");
+                _details.setForeground(Color.BLUE);
+                InstanceCellRenderer renderer = _table.getInstanceRenderer();
+                for (Object e : coll) {
+                    _details.append(renderer.renderAsString(e) + "\r\n");
+                }
+            }
+        }
+    }
+}

Propchange: openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/EntityTableView.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/EntityTypeView.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/EntityTypeView.java?rev=944083&view=auto
==============================================================================
--- openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/EntityTypeView.java (added)
+++ openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/EntityTypeView.java Fri May 14 02:14:30 2010
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2010-2012 Pinaki Poddar
+ *
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+*/
+package jpa.tools.swing;
+
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.GridLayout;
+import java.awt.Point;
+import java.util.List;
+
+import javax.persistence.metamodel.Attribute;
+import javax.persistence.metamodel.EntityType;
+import javax.swing.BorderFactory;
+import javax.swing.JComponent;
+import javax.swing.JPanel;
+
+/**
+ * View of a persistent entity type as a JPanel.
+ * 
+ * @author Pinaki Poddar
+ *
+ */
+@SuppressWarnings("serial")
+public class EntityTypeView<T> extends JPanel {
+    final EntityType<T> type;
+    final int hgap = 4;
+    final int vgap = 4;
+    
+    public EntityTypeView(EntityType<T> type) {
+        this.type = type;
+        GridLayout layout = new GridLayout(0,1);
+        setLayout(layout);
+        layout.setVgap(vgap);
+        layout.setHgap(hgap);
+        
+        setBackground(Color.WHITE);
+        setBorder(BorderFactory.createTitledBorder(MetamodelHelper.getDisplayName(type)));
+
+        int w = 0;
+        int h = 0;
+        List<Attribute<? super T,?>> attrs = MetamodelHelper.getAttributes(type);
+        for (Attribute<? super T,?> attr : attrs) {
+            JComponent c = new AttributeView(attr);
+            add(c);
+            w  = Math.max(w, c.getPreferredSize().width);
+            h += c.getPreferredSize().height + 2*vgap;
+        }
+//        setPreferredSize(new Dimension(w,h));
+    }
+    
+    public EntityType<T> getEntityType() {
+        return type;
+    }
+    
+    
+    /**
+     * Gets the top left position of the attribute label relative to this entity view.
+     * @param attr
+     * @return
+     */
+    public Point getPosition(Attribute<?,?> attr) {
+        for (Component c : getComponents()) {
+            if (c instanceof AttributeView) {
+                if (((AttributeView)c).getAttribute().equals(attr)) {
+                    return new Point(c.getLocation().x, c.getLocation().y + c.getHeight()/2);
+                }
+            }
+        }
+        return new Point(0,0);
+    }
+}
+
+

Propchange: openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/EntityTypeView.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/ErrorDialog.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/ErrorDialog.java?rev=944083&view=auto
==============================================================================
--- openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/ErrorDialog.java (added)
+++ openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/ErrorDialog.java Fri May 14 02:14:30 2010
@@ -0,0 +1,157 @@
+/*
+ * Copyright 2010-2012 Pinaki Poddar
+ *
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+*/
+package jpa.tools.swing;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.swing.BorderFactory;
+import javax.swing.Icon;
+import javax.swing.ImageIcon;
+import javax.swing.JButton;
+import javax.swing.JComponent;
+import javax.swing.JDialog;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTextArea;
+import javax.swing.JTextPane;
+import javax.swing.text.AttributeSet;
+import javax.swing.text.SimpleAttributeSet;
+import javax.swing.text.StyleConstants;
+import javax.swing.text.StyleContext;
+
+@SuppressWarnings("serial")
+public class ErrorDialog extends JDialog {
+    private static List<String> filters = Arrays.asList("java.awt.", "javax.swing.", "sun.reflect.");
+    private static AttributeSet red, black;
+    static {
+        StyleContext ctx = StyleContext.getDefaultStyleContext();
+        red = ctx.addAttribute(SimpleAttributeSet.EMPTY, StyleConstants.Foreground, Color.RED);
+        red = ctx.addAttribute(red, StyleConstants.Bold, true);
+        red = ctx.addAttribute(red, StyleConstants.FontSize, 12);
+        red = ctx.addAttribute(red, StyleConstants.FontFamily, "Courier");
+        black = ctx.addAttribute(SimpleAttributeSet.EMPTY, StyleConstants.Foreground, Color.BLACK);
+        black = ctx.addAttribute(black, StyleConstants.Bold, false);
+        black = ctx.addAttribute(black, StyleConstants.FontFamily, "Courier");
+    }
+
+    public ErrorDialog(JComponent owner, Throwable t) {
+        super();
+        setModal(true);
+        setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
+//        Icon icon = Images.ERROR;
+//        setIconImage(((ImageIcon)icon).getImage());
+        addException(t);
+        pack();
+        SwingHelper.position(this, owner);
+    }
+    
+    public ErrorDialog(Throwable t) {
+        this(null, t);
+    }
+    
+    void addException(Throwable t) {
+        setTitle("Error");
+        String txt = t.getClass().getName() + ":" + t.getLocalizedMessage();
+        JTextArea message = new JTextArea(txt);
+        message.setLineWrap(true);
+        message.setWrapStyleWord(true);
+        message.setForeground(Color.RED);
+        message.setText(txt);
+        message.setEditable(false);
+        
+        JTextPane window = new JTextPane();
+        printStackTrace(t, window);
+        window.setEditable(false);
+        JScrollPane pane = new JScrollPane(window, 
+                JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, 
+                JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
+        pane.setPreferredSize(new Dimension(400, 200));
+        pane.setBorder(BorderFactory.createTitledBorder("Stacktrace"));
+        pane.setPreferredSize(new Dimension(400, 200));
+        JPanel main = new JPanel();
+        main.setLayout(new BorderLayout());
+        main.add(message, BorderLayout.NORTH);
+        main.add(pane, BorderLayout.CENTER);
+        JPanel buttonPanel = new JPanel();
+        JButton ok = new JButton("OK");
+        ok.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent e) {
+                ErrorDialog.this.dispose();
+            }
+        });
+        buttonPanel.add(ok);
+        main.add(buttonPanel, BorderLayout.SOUTH);
+        getContentPane().add(main);
+    }
+    static String NEWLINE = "\r\n";
+    StringBuilder printStackTrace(Throwable t, JTextPane text) {
+        String message = t.getClass().getName() + ": " + t.getMessage() + NEWLINE;
+        text.setCaretPosition(text.getDocument().getLength());
+        text.setCharacterAttributes(red, false);
+        text.replaceSelection(message);
+        StackTraceElement[] traces = t.getStackTrace();
+        text.setCharacterAttributes(black, false);
+        for (StackTraceElement e : traces) {
+            if (!isFiltered(e.getClassName())) {
+                String str = "   " + e.toString() + NEWLINE;
+                text.setCaretPosition(text.getDocument().getLength());
+                text.replaceSelection(str);
+            }
+        }
+        
+        Throwable cause = t.getCause();
+        if (cause !=null && cause != t) {
+            printStackTrace(cause, text);
+        }
+        return null;
+    }
+    
+    StringBuilder toString(StackTraceElement[] traces) {
+        StringBuilder error = new StringBuilder();
+        for (StackTraceElement e : traces) {
+            if (!isFiltered(e.getClassName())) {
+                String str = e.toString();
+                error.append(str).append("\r\n");
+            }
+        }
+        return error;
+    }
+    
+    private boolean isFiltered(String className) {
+        for (String s : filters) {
+            if (className.startsWith(s))
+                return true;
+        }
+        return false;
+    }
+    
+    /**
+     * @param args
+     */
+    public static void main(String[] args) {
+        new ErrorDialog(new IllegalArgumentException(
+                "This is test error with very long line of error message that should not be in a single line"))
+        .setVisible(true);
+    }
+
+}

Propchange: openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/ErrorDialog.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/FileScanner.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/FileScanner.java?rev=944083&view=auto
==============================================================================
--- openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/FileScanner.java (added)
+++ openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/FileScanner.java Fri May 14 02:14:30 2010
@@ -0,0 +1,41 @@
+package jpa.tools.swing;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+public class FileScanner {
+    private String ext;
+    boolean recursive;
+    
+    public FileScanner(String ext, boolean recurse) {
+        this.ext = ext;
+        this.recursive = recurse;
+    }
+    
+    /**
+     * Scans the given  
+     * @param root
+     * @return
+     */
+    public List<File> scan(File dir) {
+        List<File> bag = new ArrayList<File>();
+        scan(dir, bag);
+        return bag;
+    }
+    
+    private void scan(File dir, List<File> bag) {
+        if (dir == null || !dir.exists() || !dir.isDirectory())
+            return;
+        File[] all = dir.listFiles();
+        for (File f : all) {
+            if (ext == null || f.getName().endsWith(ext)) {
+                bag.add(f);
+            }
+            if (recursive && f.isDirectory()) {
+                scan(f, bag);
+            }
+        }
+    }
+    
+}

Propchange: openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/FileScanner.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/Finder.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/Finder.java?rev=944083&view=auto
==============================================================================
--- openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/Finder.java (added)
+++ openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/Finder.java Fri May 14 02:14:30 2010
@@ -0,0 +1,111 @@
+package jpa.tools.swing;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
+/**
+ * Searches for a given class in the set of directories recursively.
+ * If a given directory contains jar file then searches inside the jar.
+ * 
+ *  Usage
+ *  $ java find.Finder class dir1 dir2...
+ *  where
+ *     class is fully qualified class name
+ *     dir name of a file system directory
+ *  
+ *  Example
+ *     $ java find.Finder org.eclipse.ui.plugin.AbstractUIPlugin c:\eclipse\plugins
+ *  will print
+ *      org.eclipse.ui.plugin.AbstractUIPlugin found in c:\eclipse\plugins\org.eclipse.ui.workbench_3.4.1.M20080827-0800a.jar
+ *      
+ * @author Pinaki Poddar
+ *
+ */
+public class Finder {
+    private static final String CLASS_SUFFIX = ".class";
+    private static final String JAR_SUFFIX = ".jar";
+    private static final char DOT = '.';
+    private static final boolean DEBUG = false;
+    
+    private static void usage() {
+        System.err.println("Searches a given class in the given directories."
+        + "\r\nIf a given directory contains jar then searches within the jar."
+        + "\r\nIf a given directory contains other directories then searches "
+        + "recursively.\r\n");
+        System.err.println("\r\n Usage:");
+        System.err.println(" $ java find.Finder class dir [dir...]");
+        System.err.println(" where");
+        System.err.println("   class fully-qualified class name");
+        System.err.println("   dir name of a directory");
+        System.err.println("\r\n Example:");
+        System.err.println(" $ java find.Finder java.lang.Object c:\\java");
+    }
+    
+    public static void main(String[] args) throws Exception {
+        if (args.length < 2) {
+            usage();
+            System.exit(0);
+        }
+        Finder finder = new Finder();
+        for (int i = 1; i < args.length; i++) {
+            File root = new File(args[i]);
+            finder.scan(root, args[0]);
+        }
+    }
+    
+    private void scan(File dir, String cls) throws IOException {
+        File[] classes = dir.listFiles(new FileFilter() {
+            public boolean accept(File path) {
+                return path.getName().endsWith(CLASS_SUFFIX);
+            }
+        });
+        String clsName = cls+CLASS_SUFFIX;
+        for (File c : classes) {
+            String name = c.getName().replace(File.separatorChar, DOT);
+            if (name.endsWith(clsName))
+                System.err.println(cls + " found in " + c.getAbsolutePath());
+        }
+
+        File[] jars = dir.listFiles(new FileFilter() {
+            public boolean accept(File path) {
+                return path.getName().endsWith(JAR_SUFFIX);
+            }
+        });
+        
+        for (File jar : jars) {
+            JarFile jarFile = new JarFile(jar);
+            scan(jarFile, cls);
+        }
+        
+        File[] dirs = dir.listFiles(new FileFilter() {
+            public boolean accept(File path) {
+                return path.isDirectory();
+            }
+        });
+        for (File cdir : dirs) 
+            scan(cdir, cls);
+    }
+    
+    private void scan(JarFile jar, String cls) {
+        String clsName = cls.replace('.', '/') + CLASS_SUFFIX;
+        debug("Scanning " + jar.getName() + " for [" + clsName + "]");
+        Enumeration<JarEntry> entries = jar.entries();
+        while (entries.hasMoreElements()) {
+            JarEntry entry = entries.nextElement();
+            String entryName = entry.getName();
+            if (entryName.endsWith(CLASS_SUFFIX))
+                debug("  " + entryName);
+            if (entryName.equals(clsName))
+                System.err.println(cls + " found in " + jar.getName());
+        }
+    }
+    
+    private void debug(String s) {
+        if (DEBUG)
+            System.err.println(s);
+    }
+}

Propchange: openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/Finder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/GraphicOutputStream.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/GraphicOutputStream.java?rev=944083&view=auto
==============================================================================
--- openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/GraphicOutputStream.java (added)
+++ openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/GraphicOutputStream.java Fri May 14 02:14:30 2010
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2010-2012 Pinaki Poddar
+ *
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+*/
+package jpa.tools.swing;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.swing.text.AttributeSet;
+import javax.swing.text.StyleContext;
+
+/**
+ * An output stream that uses a {@link ScrollingTextPane} as its sink.
+ * Flushes the buffer at line end.
+ * 
+ * @author Pinaki Poddar
+ *
+ */
+public class GraphicOutputStream extends OutputStream {
+    ScrollingTextPane _sink;
+    private char[] buffer = new char[1024];
+    private int count;
+    private Map<String, AttributeSet> _styles = new HashMap<String, AttributeSet>();
+    private static AttributeSet _defaultStyle = StyleContext.getDefaultStyleContext()
+                                                            .getStyle(StyleContext.DEFAULT_STYLE);
+    
+    public GraphicOutputStream(ScrollingTextPane delegate) {
+        _sink = delegate;
+    }
+    
+    public void registerStyle(String pattern, AttributeSet style) {
+        _styles.put(pattern, style);
+    }
+    
+    @Override
+    public void write(int b) throws IOException {
+        buffer[count++] = (char)b;
+        if (count > buffer.length || b == '\r' || b == '\n') {
+            flushBuffer();
+        }
+    }
+    
+    private void flushBuffer() {
+        String txt = new String(buffer, 0, count);
+        count = 0;
+        AttributeSet style = getStyle(txt);
+        _sink.setCharacterAttributes(style, true);
+        _sink.appendText(txt);
+    }
+    
+    AttributeSet getStyle(String txt) {
+        if (txt == null || txt.isEmpty())
+            return _defaultStyle;
+        for (String pattern : _styles.keySet()) {
+            if (txt.startsWith(pattern))
+                return _styles.get(pattern);
+        }
+        return _defaultStyle;
+    }
+
+}

Propchange: openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/GraphicOutputStream.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/ImageBorder.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/ImageBorder.java?rev=944083&view=auto
==============================================================================
--- openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/ImageBorder.java (added)
+++ openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/ImageBorder.java Fri May 14 02:14:30 2010
@@ -0,0 +1,134 @@
+/*
+ * Copyright 2010-2012 Pinaki Poddar
+ *
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+*/
+package jpa.tools.swing;
+
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Image;
+import java.awt.Insets;
+import java.awt.Rectangle;
+import java.awt.TexturePaint;
+import java.awt.image.BufferedImage;
+
+import javax.swing.border.AbstractBorder;
+
+@SuppressWarnings("serial")
+public class ImageBorder extends AbstractBorder {
+
+    Image image;
+    String title;
+    
+//    Image topCenterImage, topLeftImage, topRight;
+//
+//    Image leftCenterImage, rightCenterImage;
+//
+//    Image bottomCenterImage, bottomLeftImage, bottomRightImage;
+
+    Insets insets;
+
+    public ImageBorder(Image img, String title) {
+        image = img;
+        this.title = title;
+    }
+//    public ImageBorder(Image top_left, Image top_center, Image top_right, Image left_center,
+//        Image right_center, Image bottom_left, Image bottom_center, Image bottom_right) {
+//
+//      this.topLeftImage = top_left;
+//      this.topCenterImage = top_center;
+//      this.topRight = top_right;
+//      this.leftCenterImage = left_center;
+//      this.rightCenterImage = right_center;
+//      this.bottomLeftImage = bottom_left;
+//      this.bottomCenterImage = bottom_center;
+//      this.bottomRightImage = bottom_right;
+//    }
+
+    public void setInsets(Insets insets) {
+      this.insets = insets;
+    }
+
+    public Insets getBorderInsets(Component c) {
+      if (insets != null) {
+        return insets;
+      } else {
+//          return new Insets(topCenterImage.getHeight(null), leftCenterImage.getWidth(null), bottomCenterImage
+//                  .getHeight(null), rightCenterImage.getWidth(null));
+          return new Insets(image.getHeight(null), 100,10,100);
+      }
+    }
+
+    public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
+      g.setColor(Color.white);
+      g.fillRect(x, y, width, height);
+      g.setColor(Color.black);
+      
+      Graphics2D g2 = (Graphics2D) g;
+      int tlw = image.getWidth(null);
+      int tlh = image.getHeight(null);
+      fillTexture(g2, image, x, y, tlw, tlh);
+      g2.drawString(title, tlw, 10);
+
+//      int tlw = topLeftImage.getWidth(null);
+//      int tlh = topLeftImage.getHeight(null);
+//      int tcw = topCenterImage.getWidth(null);
+//      int tch = topCenterImage.getHeight(null);
+//      int trw = topRight.getWidth(null);
+//      int trh = topRight.getHeight(null);
+//
+//      int lcw = leftCenterImage.getWidth(null);
+//      int lch = leftCenterImage.getHeight(null);
+//      int rcw = rightCenterImage.getWidth(null);
+//      int rch = rightCenterImage.getHeight(null);
+//
+//      int blw = bottomLeftImage.getWidth(null);
+//      int blh = bottomLeftImage.getHeight(null);
+//      int bcw = bottomCenterImage.getWidth(null);
+//      int bch = bottomCenterImage.getHeight(null);
+//      int brw = bottomRightImage.getWidth(null);
+//      int brh = bottomRightImage.getHeight(null);
+
+//      fillTexture(g2, topLeftImage, x, y, tlw, tlh);
+//      fillTexture(g2, topCenterImage, x + tlw, y, width - tlw - trw, tch);
+//      fillTexture(g2, topRight, x + width - trw, y, trw, trh);
+//
+//      fillTexture(g2, leftCenterImage, x, y + tlh, lcw, height - tlh - blh);
+//      fillTexture(g2, rightCenterImage, x + width - rcw, y + trh, rcw, height - trh - brh);
+//
+//      fillTexture(g2, bottomLeftImage, x, y + height - blh, blw, blh);
+//      fillTexture(g2, bottomCenterImage, x + blw, y + height - bch, width - blw - brw, bch);
+//      fillTexture(g2, bottomRightImage, x + width - brw, y + height - brh, brw, brh);
+    }
+
+    public void fillTexture(Graphics2D g2, Image img, int x, int y, int w, int h) {
+      BufferedImage buff = createBufferedImage(img);
+      Rectangle anchor = new Rectangle(x, y, img.getWidth(null), img.getHeight(null));
+      TexturePaint paint = new TexturePaint(buff, anchor);
+      g2.setPaint(paint);
+      g2.fillRect(x, y, w, h);
+    }
+
+    public BufferedImage createBufferedImage(Image img) {
+      BufferedImage buff = new BufferedImage(img.getWidth(null), img.getHeight(null),
+          BufferedImage.TYPE_INT_ARGB);
+      Graphics gfx = buff.createGraphics();
+      gfx.drawImage(img, 0, 0, null);
+      gfx.dispose();
+      return buff;
+    }
+  }
\ No newline at end of file

Propchange: openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/ImageBorder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/InstanceDataModel.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/InstanceDataModel.java?rev=944083&view=auto
==============================================================================
--- openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/InstanceDataModel.java (added)
+++ openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/InstanceDataModel.java Fri May 14 02:14:30 2010
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2010-2012 Pinaki Poddar
+ *
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+*/
+package jpa.tools.swing;
+
+import java.util.List;
+
+import javax.persistence.metamodel.Attribute;
+import javax.persistence.metamodel.EntityType;
+import javax.swing.table.AbstractTableModel;
+
+@SuppressWarnings("serial")
+public class InstanceDataModel<T> extends AbstractTableModel {
+    List<Attribute<? super T, ?>> attributes;
+    private T _instance;
+
+    public InstanceDataModel(EntityType<T> type, T instance) {
+        super();
+        attributes = MetamodelHelper.getAttributes(type);
+        this._instance = instance;
+    }
+
+    @Override
+    public Class<?> getColumnClass(int columnIndex) {
+        return columnIndex == 0 ? String.class : Object.class;
+    }
+
+    @Override
+    public int getColumnCount() {
+        return 2;
+    }
+
+    @Override
+    public String getColumnName(int columnIndex) {
+        return columnIndex == 0 ? "Properties" : "Value";
+    }
+
+    @Override
+    public int getRowCount() {
+        return attributes.size();
+    }
+
+    @Override
+    public Object getValueAt(int rowIndex, int columnIndex) {
+        Attribute<? super T, ?> attr = attributes.get(rowIndex);
+        return columnIndex == 0 ?  attr.getName() : MetamodelHelper.getValue(attr, _instance);
+    }
+
+    @Override
+    public boolean isCellEditable(int rowIndex, int columnIndex) {
+        return false;
+    }
+
+    @Override
+    public void setValueAt(Object value, int rowIndex, int columnIndex) {
+    }
+
+}

Propchange: openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/InstanceDataModel.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/InstanceView.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/InstanceView.java?rev=944083&view=auto
==============================================================================
--- openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/InstanceView.java (added)
+++ openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/InstanceView.java Fri May 14 02:14:30 2010
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2010-2012 Pinaki Poddar
+ *
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+*/
+package jpa.tools.swing;
+
+import javax.persistence.metamodel.EntityType;
+import javax.swing.BorderFactory;
+import javax.swing.JTable;
+
+@SuppressWarnings("serial")
+public class InstanceView<T> extends JTable {
+    public InstanceView(EntityType<T> type, T instance) {
+        super(new InstanceDataModel<T>(type, instance));
+        setShowHorizontalLines(false);
+        setShowVerticalLines(false);
+    }
+}

Propchange: openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/InstanceView.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/Maze.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/Maze.java?rev=944083&view=auto
==============================================================================
--- openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/Maze.java (added)
+++ openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/Maze.java Fri May 14 02:14:30 2010
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2010-2012 Pinaki Poddar
+ *
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+*/
+package jpa.tools.swing;
+
+public interface Maze {
+    boolean isReachable(int x, int y);
+}

Propchange: openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/Maze.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/MetamodelHelper.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/MetamodelHelper.java?rev=944083&view=auto
==============================================================================
--- openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/MetamodelHelper.java (added)
+++ openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/MetamodelHelper.java Fri May 14 02:14:30 2010
@@ -0,0 +1,284 @@
+/*
+ * Copyright 2010-2012 Pinaki Poddar
+ *
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+*/
+package jpa.tools.swing;
+
+import java.awt.Color;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.persistence.metamodel.Attribute;
+import javax.persistence.metamodel.CollectionAttribute;
+import javax.persistence.metamodel.EntityType;
+import javax.persistence.metamodel.MapAttribute;
+import javax.persistence.metamodel.PluralAttribute;
+import javax.persistence.metamodel.SingularAttribute;
+import javax.persistence.metamodel.Type;
+
+/**
+ * Static utility for analyzing persistent metadata model using JPA 2.0.
+ *  
+ * @author Pinaki Poddar
+ *
+ */
+public class MetamodelHelper {
+    public static final int ATTR_ID      = 0;
+    public static final int ATTR_VERSION = 1;
+    public static final int ATTR_BASIC   = 2;
+    public static final int ATTR_SINGULAR_RELATION = 3;
+    public static final int ATTR_PLURAL_RELATION   = 4;
+    
+    public static final Color MIDNIGHT_BLUE = new Color(25,25,112);
+    public static final Color DARK_GREEN = new Color(0,100,0);
+    public static final Color KHAKI = new Color(240, 230, 140);
+    
+    public static String getDisplayName(Type<?> type) {
+        if (type instanceof EntityType) {
+            return getDisplayName((EntityType<?>)type);
+        }
+        return getDisplayName(type.getJavaType());
+    }
+    
+    /**
+     * Gets the displayed name of a given entity type.
+     * @param type
+     * @return
+     */
+    public static String getDisplayName(EntityType<?> type) {
+        return type.getName();
+    }
+    
+    public static String getDisplayName(Class<?> cls) {
+      String fullName = cls.getName();
+      if (fullName.startsWith("java.") || fullName.startsWith("openbook.domain.")) {
+          int i = fullName.lastIndexOf('.');
+          return fullName.substring(i+1);
+      }
+      return fullName;
+    }
+    
+    
+    public static String getDisplayName(Attribute<?,?> attr) {
+        StringBuilder buffer = new StringBuilder();
+        buffer.append(getDisplayName(attr.getJavaType()));
+        if (attr instanceof MapAttribute) {
+            buffer.append("<").append(getDisplayName(((MapAttribute)attr).getKeyType())).append(",")
+                  .append(getDisplayName(((MapAttribute)attr).getElementType())).append(">");
+        } else if (attr instanceof PluralAttribute) {
+            buffer.append("<").append(getDisplayName(((PluralAttribute)attr).getElementType())).append(">");
+        } 
+        buffer.append(" ").append(attr.getName());
+        return buffer.toString();
+    }
+    
+    
+    public static <T> List<Attribute<? super T,?>> getAttributes(EntityType<T> type) {
+        List<Attribute<? super T,?>> list = new ArrayList<Attribute<? super T,?>>(type.getAttributes());
+        Collections.sort(list, new AttributeComparator());
+        return list;
+    }
+    
+    public static int getAttributeType(Attribute<?, ?> a) {
+        if (a instanceof SingularAttribute) {
+            SingularAttribute<?, ?> sa = (SingularAttribute<?, ?>)a;
+            if (sa.isId()) return ATTR_ID;
+            if (sa.isVersion()) return ATTR_VERSION;
+            if (sa.isAssociation()) return ATTR_SINGULAR_RELATION;
+            if (sa.isCollection()) return ATTR_PLURAL_RELATION;
+        } else {
+            if (a.isAssociation()) return ATTR_SINGULAR_RELATION;
+            if (a.isCollection()) return ATTR_PLURAL_RELATION;
+        }
+        return ATTR_BASIC;
+        
+    }
+    
+    public static <T> Set<SingularAttribute<? super T, ?>> getIdAttributes(EntityType<T> type) {
+        Set<SingularAttribute<? super T,?>> attrs = type.getSingularAttributes();
+        Set<SingularAttribute<? super T,?>> idAttrs = new HashSet<SingularAttribute<? super T,?>>();
+        for (SingularAttribute<? super T,?> attr : attrs) {
+            if (attr.isId()) {
+                idAttrs.add(attr);
+            }
+        }
+        return idAttrs;
+    }
+    
+    /**
+     * Finds the derived target of the given type, if any. Otherwise null.
+     */
+    public static <T> EntityType<?> derivedTarget(EntityType<T> type) {
+        Set<SingularAttribute<? super T,?>> ids = getIdAttributes(type);
+        for (SingularAttribute<? super T,?> id : ids) {
+            EntityType<?> derived = getParentType(id);
+            if (derived != null) {
+                return derived;
+            }
+        }
+        return null;
+    }
+    
+    public static EntityType<?> getParentType(SingularAttribute<?,?> id) {
+        if (id.getType() instanceof EntityType) {
+            return (EntityType<?>)id.getType();
+        }
+        return null;
+    }
+
+    
+    public static boolean isId(Attribute<?,?> a) {
+        if (a instanceof SingularAttribute)
+            return ((SingularAttribute<?,?>)a).isId();
+        return false;
+    }
+    public static boolean isVersion(Attribute<?,?> a) {
+        if (a instanceof SingularAttribute)
+            return ((SingularAttribute<?,?>)a).isVersion();
+        return false;
+    }
+    
+    public static Color getColor(Attribute<?,?> attr) {
+        if (isId(attr))
+            return Color.RED;
+        if (isVersion(attr))
+            return Color.DARK_GRAY;
+        return getColor(attr.getPersistentAttributeType());
+    }
+    
+    public static Color getColor(Attribute.PersistentAttributeType type) {
+        switch (type) {
+        case BASIC :             return Color.BLACK;
+        case EMBEDDED:           return Color.GRAY;
+        case ONE_TO_ONE:         return Color.BLUE;
+        case MANY_TO_ONE:        return MIDNIGHT_BLUE;
+        case ONE_TO_MANY:        return DARK_GREEN;
+        case MANY_TO_MANY:       return Color.PINK;
+        case ELEMENT_COLLECTION: return KHAKI;
+        default:                 return Color.BLACK;
+        }
+    }
+    
+    public static Integer getAttributeTypeCode(Attribute<?,?> attr) {
+        if (isId(attr))
+            return 0;
+        if (isVersion(attr))
+            return 1;
+        
+      switch (attr.getPersistentAttributeType()) {
+      case BASIC : 
+      case EMBEDDED:
+          return 2;
+      case ONE_TO_ONE: 
+      case MANY_TO_ONE:
+          return 3;
+      case ONE_TO_MANY:
+      case MANY_TO_MANY:
+      case ELEMENT_COLLECTION: return 4;
+      default: return 5;
+      }
+    }
+    private static Map<Attribute<?,?>, Method> members = new HashMap<Attribute<?,?>, Method>();
+    private static Object[] EMPTY_ARGS = null;
+    private static Class<?>[] EMPTY_CLASSES = null;
+    /**
+     * Gets the value of the given persistent attribute for the given instance.
+     * @param attr
+     * @param instance
+     * @return
+     */
+    public static Object getValue(Attribute<?,?> attr, Object instance) {
+        Member member = attr.getJavaMember();
+        Method getter = null;
+        if (member instanceof Method) {
+            getter = (Method)member;
+        } else if (members.containsKey(attr)) {
+            getter = members.get(attr);
+        } else {
+            getter = getMethod(attr.getDeclaringType().getJavaType(), attr.getName());
+            members.put(attr, getter);
+        }
+        if (getter == null)
+            return null;
+        try {
+            return getter.invoke(instance, EMPTY_ARGS);
+        } catch (Exception e) {
+            return null;
+        }
+    }
+    
+    private static Method getMethod(Class<?> type, String p) {
+        try {
+            String getter = "get" + Character.toUpperCase(p.charAt(0))+p.substring(1);
+            return type.getMethod(getter, EMPTY_CLASSES);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return null;
+        
+    }
+
+    
+    /**
+     * Compares EntityType by their dependency of derived targets.
+     * 
+     * @author Pinaki Poddar
+     *
+     */
+    public static class EntityComparator implements Comparator<EntityType<?>> {
+        @Override
+        public int compare(EntityType<?> o1, EntityType<?> o2) {
+            if (derivedTarget(o1) == o2)
+               return 1;
+            if (derivedTarget(o2) == o1)
+                return -1;
+            return o1.getName().compareTo(o2.getName());
+        }
+        
+    }
+
+    
+    /**
+     * Compares attribute by their qualification.
+     * Identity 
+     * Version
+     * Basic
+     * Singular association
+     * Plural association
+     *  
+     * @author Pinaki Poddar
+     *
+     */
+    public static class AttributeComparator implements Comparator<Attribute<?,?>> {
+        @Override
+        public int compare(Attribute<?, ?> a1, Attribute<?, ?> a2) {
+            Integer t1 = getAttributeTypeCode(a1);
+            Integer t2 = getAttributeTypeCode(a2);
+            if (t1.equals(t2)) {
+                return a1.getName().compareTo(a2.getName());
+            } else {
+                return t1.compareTo(t2);
+            }
+        }
+    }
+}

Propchange: openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/MetamodelHelper.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/MetamodelView.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/MetamodelView.java?rev=944083&view=auto
==============================================================================
--- openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/MetamodelView.java (added)
+++ openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/MetamodelView.java Fri May 14 02:14:30 2010
@@ -0,0 +1,154 @@
+/*
+ * Copyright 2010-2012 Pinaki Poddar
+ *
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+*/
+package jpa.tools.swing;
+
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.FlowLayout;
+import java.awt.Graphics;
+import java.awt.Insets;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+import javax.persistence.metamodel.Attribute;
+import javax.persistence.metamodel.EntityType;
+import javax.persistence.metamodel.Metamodel;
+import javax.persistence.metamodel.SingularAttribute;
+import javax.swing.JPanel;
+import javax.swing.SwingConstants;
+
+
+/**
+ * Graphical View of a JPA 2.0 Metamodel.
+ * The view is isomorphic to the {@link Metamodel meta-model} defined by JPA 2.0 specification.
+ * Hence the view is organized in terms of corresponding views of {@link EntityTypeView entity}
+ * and their {@link AttributeView attributes}.
+ * <br>
+ * This view also draws linkage with A*-algorithm between the derived primary key attributes that 
+ * reference other entity types.   
+ * 
+ * @author Pinaki Poddar
+ *
+ */
+@SuppressWarnings("serial")
+public class MetamodelView extends JPanel implements Maze {
+    
+    private static final int GRID = 8;
+    int hgap = 40;
+    int vgap = 40;
+    
+    /**
+     * Creates a panel where each {@link EntityTypeView} is placed in a FlowLayout.
+     * Only the entities of the model are ordered based on their primary key 
+     * dependencies, if any.
+     * 
+     * @param model
+     */
+    @SuppressWarnings("unchecked")
+    public MetamodelView(Metamodel model) {
+        super(true);
+        FlowLayout layout = (FlowLayout)getLayout();
+        layout.setHgap(80);
+        layout.setVgap(80);
+//        getInsets(new Insets(100,100,100,100));
+        Set<EntityType<?>> types = model.getEntities();
+        List<EntityType<?>> sorted = new ArrayList<EntityType<?>>(types);
+        Collections.sort(sorted, new MetamodelHelper.EntityComparator());
+        for (EntityType type : sorted) {
+            EntityTypeView view = new EntityTypeView(type);
+            add(view);
+        }
+    }
+    
+    EntityTypeView<?> findViewByType(EntityType<?> type) {
+        if (type == null)
+            return null;
+        for (Component c : getComponents()) {
+            if (c instanceof EntityTypeView) {
+                EntityTypeView<?> view = (EntityTypeView<?>)c;
+                if (view.getEntityType().equals(type)) {
+                    return view;
+                }
+            }
+        }
+        return null;
+    }
+    
+    @Override
+    public void paint(Graphics g) {
+        super.paint(g);
+        for (Component c : getComponents()) {
+            if (c instanceof EntityTypeView == false) {
+                continue;
+            }
+            EntityTypeView<?> view = (EntityTypeView<?>)c;
+            for (SingularAttribute<?,?> id : MetamodelHelper.getIdAttributes(view.getEntityType())) {
+                EntityTypeView<?> target = findViewByType(MetamodelHelper.getParentType(id));
+                if (target == null)
+                    continue;
+                
+                PathFinder runner = new PathFinder(this);
+                Point start = getConnectLocation(view, id);
+                Point finish = target.getLocation();
+                List<Point> path = runner.findPath(start.x/GRID, start.y/GRID, 
+                        finish.x/GRID, finish.y/GRID);
+                if (path.isEmpty())
+                    continue;
+                Point p1 = path.get(0);
+                Point p2 = null;
+                for (int i = 1; i < path.size(); i++) {
+                    p2 = path.get(i);
+                    g.drawLine(p1.x*GRID, p1.y*GRID, p2.x*GRID, p2.y*GRID);
+                    p1 = p2;
+                }
+                g.setColor(Color.BLACK);
+                int r = 4;
+                g.fillOval(p1.x*GRID -r, p1.y*GRID - r, 2*r, 2*r);
+                
+            }
+        }
+    }
+    
+    /**
+     * Gets the position of the attribute in the entity view relative to this panel. 
+     * @param a
+     * @param attr
+     * @return
+     */
+    Point getConnectLocation(EntityTypeView<?> a, Attribute<?,?> attr) {
+        Point p1 = a.getLocation();
+        Point p2 = a.getPosition(attr);
+        return new Point(p1.x + p2.x, p1.y + p2.y);
+    }
+    
+    // contract for the maze
+    @Override
+    public boolean isReachable(int x, int y) {
+        for (Component view : getComponents()) {
+            Rectangle r = view.getBounds();
+            int px = x*GRID;
+            int py = y*GRID;
+            if (r.contains(px, py)) 
+                return false;
+        }
+        return true;
+    }
+}

Propchange: openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/MetamodelView.java
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message