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
|