You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by pp...@apache.org on 2010/05/14 04:14:32 UTC
svn commit: r944083 [3/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...
Added: openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/client/Demo.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/client/Demo.java?rev=944083&view=auto
==============================================================================
--- openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/client/Demo.java (added)
+++ openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/client/Demo.java Fri May 14 02:14:30 2010
@@ -0,0 +1,634 @@
+/*
+ * 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 openbook.client;
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.Cursor;
+import java.awt.Dimension;
+import java.awt.event.ActionEvent;
+import java.io.PrintStream;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.Box;
+import javax.swing.Icon;
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JScrollPane;
+import javax.swing.JSplitPane;
+import javax.swing.JTabbedPane;
+import javax.swing.JToolBar;
+import javax.swing.JTree;
+import javax.swing.SwingConstants;
+import javax.swing.SwingUtilities;
+import javax.swing.SwingWorker;
+import javax.swing.event.TreeSelectionEvent;
+import javax.swing.event.TreeSelectionListener;
+import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.tree.DefaultTreeCellRenderer;
+
+import jpa.tools.swing.AttributeLegendView;
+import jpa.tools.swing.ConfigurationViewer;
+import jpa.tools.swing.ErrorDialog;
+import jpa.tools.swing.GraphicOutputStream;
+import jpa.tools.swing.MetamodelView;
+import jpa.tools.swing.PowerPointViewer;
+import jpa.tools.swing.PreparedQueryViewer;
+import jpa.tools.swing.ScrollingTextPane;
+import jpa.tools.swing.SourceCodeViewer;
+import jpa.tools.swing.StatusBar;
+import jpa.tools.swing.SwingHelper;
+import openbook.domain.Customer;
+import openbook.server.OpenBookService;
+import openbook.server.ServiceFactory;
+import openbook.util.PropertyHelper;
+
+import org.apache.openjpa.conf.OpenJPAVersion;
+import org.apache.openjpa.persistence.OpenJPAPersistence;
+
+/**
+ * A graphical user interface based client of OpenBooks for demonstration.
+ *
+ * @author Pinaki Poddar
+ *
+ */
+@SuppressWarnings("serial")
+public class Demo extends JFrame implements Thread.UncaughtExceptionHandler {
+ private static final Dimension TAB_VIEW = new Dimension(1400,800);
+ private static final Dimension OUT_VIEW = new Dimension(1400,200);
+ private static final Dimension NAV_VIEW = new Dimension(400,1000);
+
+ /**
+ * The actions invoked by this sample demonstration.
+ */
+ private Action _root;
+ private Action _about;
+ private Action _buyBook;
+ private Action _deliver;
+ private Action _supply;
+ private Action _viewConfig;
+ private Action _viewDomain;
+ private Action _viewData;
+ private Action _viewSource;
+ private Action _viewQuery;
+
+ /**
+ * The primary graphic widgets used to invoke and display the results of the actions.
+ */
+ private JToolBar _toolBar;
+ private JTree _navigator;
+ private JTabbedPane _tabbedPane;
+ private JTabbedPane _outputPane;
+ private StatusBar _statusBar;
+ private ScrollingTextPane _sqlLog;
+ public static final Icon LOGO = Images.getIcon("images/OpenBooks.jpg");
+
+ private boolean _debug = Boolean.getBoolean("openbook.debug");
+
+ /**
+ * The handle to the service.
+ */
+ private OpenBookService _service;
+ private Customer _customer;
+ private Map<String, Object> _config;
+
+ /**
+ * Runs the demo.
+ * @param args
+ * @throws Exception
+ */
+ public static void main(String[] args) throws Exception {
+ SwingHelper.setLookAndFeel(14);
+ SwingUtilities.invokeLater(new Runnable() {
+ public void run() {
+ Demo demo = new Demo();
+ demo.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+
+ demo.pack();
+ SwingHelper.position(demo, null);
+ demo.setVisible(true);
+ }
+ });
+ }
+
+
+ private Demo() {
+ Thread.currentThread().setUncaughtExceptionHandler(this);
+ _config = PropertyHelper.load(System.getProperty("openbook.client.config", "demo.properties"));
+
+ setTitle("OpenBooks: A Sample JPA 2.0 Application");
+
+ _root = new WelcomeAction("OpenBooks", "images/OpenBooks.jpg", "OpenBooks");
+ _about = new AboutAction("About OpenBooks", "images/OpenBooks.jpg", "About OpenBooks");
+ _buyBook = new BuyBookAction("Buy", "images/Add2Cart.jpg", "Browse and Buy Books");
+ _deliver = new DeliveryAction("Deliver", "images/Deliver.jpg", "Deliver Pending Orders");
+ _supply = new SupplyAction("Supply", "images/Supply.jpg", "Supply Books");
+ _viewConfig = new ViewConfigAction("Configuration", "images/browse.png", "View Configuration");
+ _viewDomain = new ViewDomainAction("Domain", "images/DomainModel.jpg", "View Domain Model");
+ _viewData = new ViewDataAction("Data", "images/DataModel.jpg", "View Instances");
+ _viewSource = new ViewSourceAction("Source", "images/SourceCode.jpg", "View Source Code");
+ _viewQuery = new ViewQueryCacheAction("Query", "images/DataModel.jpg", "View Queries");
+
+ _toolBar = createToolBar();
+ _navigator = createNavigator();
+ _tabbedPane = createTabbedView();
+ _outputPane = createOutputView();
+ _statusBar = createStatusBar();
+
+ JSplitPane horizontalSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
+ horizontalSplitPane.setContinuousLayout(true);
+ horizontalSplitPane.setDividerSize(1);
+ JScrollPane scrollPane = new JScrollPane(_navigator);
+ scrollPane.setMinimumSize(new Dimension(NAV_VIEW.width/4, NAV_VIEW.height));
+ scrollPane.setPreferredSize(NAV_VIEW);
+ horizontalSplitPane.add(scrollPane);
+
+ JSplitPane verticalSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
+ verticalSplitPane.setContinuousLayout(true);
+ verticalSplitPane.setDividerSize(1);
+ verticalSplitPane.add(_tabbedPane);
+ verticalSplitPane.add(_outputPane);
+ horizontalSplitPane.add(verticalSplitPane);
+
+ Container content = getContentPane();
+ content.add(_toolBar, BorderLayout.PAGE_START);
+ content.add(horizontalSplitPane, BorderLayout.CENTER);
+ content.add(_statusBar, BorderLayout.SOUTH);
+
+ _root.actionPerformed(null);
+ }
+
+ /**
+ * Gets the handle to OpenBooks service.
+ */
+ public OpenBookService getService() {
+ if (_service == null) {
+ final String unitName = PropertyHelper.getString(_config, "openbook.unit",
+ OpenBookService.DEFAULT_UNIT_NAME);
+
+ SwingWorker<OpenBookService, Void> getService = new SwingWorker<OpenBookService, Void> () {
+ @Override
+ protected OpenBookService doInBackground() throws Exception {
+ return ServiceFactory.getService(unitName);
+ }
+
+ };
+ getService.execute();
+ try {
+ setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
+ _service = getService.get(10, TimeUnit.SECONDS);
+ } catch (Exception t) {
+ new ErrorDialog(t).setVisible(true);
+ } finally {
+ setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
+ }
+ }
+ return _service;
+ }
+
+ public Customer getCustomer() {
+ if (_customer == null) {
+ SwingWorker<Customer, Void> task = new SwingWorker<Customer, Void> () {
+ @Override
+ protected Customer doInBackground() throws Exception {
+ return getService().login("guest");
+ }
+
+ };
+ task.execute();
+ try {
+ _customer = task.get(1, TimeUnit.SECONDS);
+ } catch (Exception t) {
+ new ErrorDialog(t).setVisible(true);
+ }
+ }
+ return _customer;
+ }
+
+ @Override
+ public void uncaughtException(Thread t, Throwable e) {
+ if (SwingUtilities.isEventDispatchThread()) {
+ new ErrorDialog(e);
+ } else {
+ e.printStackTrace();
+ }
+ }
+
+
+ private JToolBar createToolBar() {
+ JToolBar toolBar = new JToolBar();
+ toolBar.add(_buyBook);
+ toolBar.add(_deliver);
+ toolBar.add(_supply);
+ Dimension d = new Dimension(40, 32);
+ toolBar.addSeparator(d);
+
+ toolBar.add(_viewConfig);
+ toolBar.add(_viewDomain);
+ toolBar.add(_viewData);
+ toolBar.add(_viewSource);
+ toolBar.add(_viewQuery);
+
+ toolBar.addSeparator(d);
+
+ toolBar.add(Box.createHorizontalGlue());
+ toolBar.add(_about);
+ toolBar.add(Box.createHorizontalStrut(2));
+ return toolBar;
+ }
+
+ private StatusBar createStatusBar() {
+ return new StatusBar();
+ }
+
+
+ /**
+ * Abstract root of all Action objects helps to locate/configure visual action parameters such as
+ * tooltip text or image.
+ *
+ * @author Pinaki Poddar
+ *
+ */
+ public abstract class OpenBookAction extends AbstractAction {
+ public OpenBookAction(Map<String,Object> props, String key) {
+ this(PropertyHelper.getString(props, key + "name", ""),
+ PropertyHelper.getString(props, key + "icon", null),
+ PropertyHelper.getString(props, key + "tooltip", ""),
+ PropertyHelper.getString(props, key + "help", ""));
+ }
+
+ public OpenBookAction(String name, String iconLocation, String tooltip) {
+ this(name, iconLocation, tooltip, tooltip);
+ }
+
+ public OpenBookAction(String name, String iconLocation, String tooltip, String helpText) {
+ putValue(Action.NAME, name);
+ putValue(Action.SHORT_DESCRIPTION, tooltip);
+ putValue(Action.LONG_DESCRIPTION, helpText);
+
+ Icon icon = Images.getIcon(iconLocation, true);
+ putValue(Action.SMALL_ICON, icon);
+ }
+ }
+
+ public class BuyBookAction extends OpenBookAction {
+ BuyBookPage _buyBookPage;
+ public BuyBookAction(String name, String iconLocation, String tooltip) {
+ super(name, iconLocation, tooltip);
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ if (_buyBookPage == null) {
+ _buyBookPage = new BuyBookPage(getService(), getCustomer());
+ }
+ showTab(_tabbedPane, "Buy Books", _buyBookPage);
+ switchTab(_outputPane, _sqlLog);
+ }
+
+ }
+ public class DeliveryAction extends OpenBookAction {
+ DeliveryPage _deliveryPage;
+ public DeliveryAction(String name, String iconLocation, String tooltip) {
+ super(name, iconLocation, tooltip);
+ }
+ public void actionPerformed(ActionEvent e) {
+ if (_deliveryPage == null) {
+ _deliveryPage = new DeliveryPage(getService());
+ }
+ showTab(_tabbedPane, "Deliver Books", _deliveryPage);
+ switchTab(_outputPane, _sqlLog);
+ }
+
+ }
+
+ public class SupplyAction extends OpenBookAction {
+ SupplyPage _supplyPage;
+ public SupplyAction(String name, String iconLocation, String tooltip) {
+ super(name, iconLocation, tooltip);
+ }
+ public void actionPerformed(ActionEvent e) {
+ if (_supplyPage == null) {
+ _supplyPage = new SupplyPage(getService());
+ }
+ showTab(_tabbedPane, "Supply Books", _supplyPage);
+ switchTab(_outputPane, _sqlLog);
+ }
+
+ }
+
+ public class ViewConfigAction extends OpenBookAction {
+ ConfigurationViewer _configView;
+ public ViewConfigAction(String name, String iconLocation, String tooltip) {
+ super(name, iconLocation, tooltip);
+ }
+ public void actionPerformed(ActionEvent e) {
+ if (_configView == null) {
+ _configView = new ConfigurationViewer("Unit Configuration", getService().getUnit().getProperties());
+ showTab(_tabbedPane, "Configuration", new JScrollPane(_configView));
+ } else {
+ showTab(_tabbedPane, "Configuration", _configView);
+ }
+ }
+
+ }
+
+ public class ViewDomainAction extends OpenBookAction {
+ MetamodelView _domainView;
+ AttributeLegendView _legends;
+ public ViewDomainAction(String name, String iconLocation, String tooltip) {
+ super(name, iconLocation, tooltip);
+ }
+ public void actionPerformed(ActionEvent e) {
+ if (_domainView == null) {
+ _domainView = new MetamodelView(getService().getUnit().getMetamodel());
+ _legends = new AttributeLegendView();
+ showTab(_outputPane, "Legends", new JScrollPane(_legends));
+ }
+ showTab(_tabbedPane, "Domain Model", _domainView);
+ }
+
+ }
+
+ public class ViewDataAction extends OpenBookAction {
+ public ViewDataAction(String name, String iconLocation, String tooltip) {
+ super(name, iconLocation, tooltip);
+ }
+ public void actionPerformed(ActionEvent e) {
+ showTab(_tabbedPane, "Buy Books", null);
+ }
+
+ }
+
+ public class ViewQueryCacheAction extends OpenBookAction {
+ PreparedQueryViewer _queryView;
+ public ViewQueryCacheAction(String name, String iconLocation, String tooltip) {
+ super(name, iconLocation, tooltip);
+ }
+ public void actionPerformed(ActionEvent e) {
+ if (_queryView == null) {
+ _queryView = new PreparedQueryViewer(OpenJPAPersistence.cast(getService().getUnit()));
+ showTab(_tabbedPane, "JPQL Query", new JScrollPane(_queryView));
+ }
+ showTab(_tabbedPane, "JPQL Queries", _queryView);
+ }
+
+ }
+
+ public class ViewSourceAction extends OpenBookAction {
+ SourceCodeViewer _sourceViewer;
+
+ public ViewSourceAction(String name, String iconLocation, String tooltip) {
+ super(name, iconLocation, tooltip);
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ if (_sourceViewer == null) {
+ _sourceViewer = new SourceCodeViewer("source");
+ }
+ showTab(_tabbedPane, "Source Code", _sourceViewer);
+ }
+
+ }
+
+ /**
+ * Displays the "welcome" page.
+ *
+ * @author Pinaki Poddar
+ *
+ */
+ public class WelcomeAction extends OpenBookAction {
+ PowerPointViewer _powerpoint;
+ JLabel _logoLabel = new JLabel(LOGO);
+ boolean _showPresentation = true;
+
+ public WelcomeAction(String name, String iconLocation, String tooltip) {
+ super(name, iconLocation, tooltip);
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ if (_powerpoint == null && _showPresentation) {
+ String dir = PropertyHelper.getString(_config, "openbook.slides.dir", "slides/");
+ String[] defaultSlides = {
+ "Slide1.JPG",
+ "Slide2.JPG",
+ "Slide3.JPG",
+ "Slide4.JPG",
+ "Slide5.JPG",
+ "Slide6.JPG",
+ "Slide7.JPG",
+ "Slide8.JPG",
+ "Slide9.JPG",
+ "Slide10.JPG",
+ "Slide11.JPG",
+ "Slide12.JPG",
+ "Slide13.JPG",
+ "Slide14.JPG",
+ "Slide15.JPG"};
+ List<String> slides = PropertyHelper.getStringList(_config, "openbook.slides.list",
+ Arrays.asList(defaultSlides));
+ try {
+ _powerpoint = new PowerPointViewer(dir, slides);
+ } catch (Exception e1) {
+ _showPresentation = false;
+ System.err.println("Error while opening slide deck at " + dir + ". \r\n"+ e1);
+ }
+ }
+ showTab(_tabbedPane, "Home", _powerpoint != null ? _powerpoint : _logoLabel);
+ }
+
+ }
+ public class AboutAction extends OpenBookAction {
+ AboutDialog _dialog;
+
+ public AboutAction(String name, String iconLocation, String tooltip) {
+ super(name, iconLocation, tooltip);
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ if (_dialog == null) {
+ _dialog = new AboutDialog(LOGO);
+ SwingHelper.position(_dialog, Demo.this);
+ }
+ _dialog.setVisible(true);
+ }
+
+ }
+
+ /**
+ * Show the given tab in the given pane.
+ * @param pane the tabbed pane
+ * @param title title of the tab component
+ * @param tab the component to show
+ */
+ void showTab(JTabbedPane pane, String title, Component tab) {
+ if (tab == null)
+ return;
+ Component c = locateTab(pane, tab);
+ if (c == null) {
+ pane.addTab(title, tab);
+ pane.setSelectedComponent(tab);
+ } else {
+ pane.setSelectedComponent(c);
+ }
+ }
+
+ void switchTab(JTabbedPane pane, Component tab) {
+ if (tab == null)
+ return;
+ Component c = locateTab(pane, tab);
+ if (c == null) {
+ pane.setSelectedComponent(c);
+ }
+ }
+
+ Component locateTab(JTabbedPane pane, Component tab) {
+ int index = pane.indexOfComponent(tab);
+ if (index == -1) {
+ Component[] components = pane.getComponents();
+ for (int i = 0; i < components.length; i++) {
+ if (components[i] instanceof JScrollPane
+ && (((JScrollPane)components[i]).getViewport().getView() == tab)) {
+ return components[i];
+ }
+ }
+ } else {
+ return pane.getComponentAt(index);
+ }
+ return null;
+ }
+
+
+ private JTabbedPane createTabbedView() {
+ JTabbedPane pane = new JTabbedPane();
+ pane.setPreferredSize(TAB_VIEW);
+ pane.setMinimumSize(new Dimension(TAB_VIEW.width, TAB_VIEW.height));
+ return pane;
+ }
+
+ private JTabbedPane createOutputView() {
+ JTabbedPane pane = new JTabbedPane();
+ pane.setPreferredSize(OUT_VIEW);
+ _sqlLog = new ScrollingTextPane();
+ GraphicOutputStream stream = new GraphicOutputStream(_sqlLog);
+ _sqlLog.setPreferredSize(TAB_VIEW);
+ SQLLogger.setOutput(stream);
+ pane.addTab("SQL Log", new JScrollPane(_sqlLog));
+ ScrollingTextPane consoleLog = new ScrollingTextPane();
+ GraphicOutputStream console = new GraphicOutputStream(consoleLog);
+ System.setErr(new PrintStream(console, true));
+ pane.addTab("Console", new JScrollPane(consoleLog));
+ return pane;
+ }
+
+ /**
+ * Creates the navigation tree and adds the tree nodes. Each tree node is attached with an action
+ * that fires when the node is selected.
+ */
+ private JTree createNavigator() {
+ ActionTreeNode root = new ActionTreeNode(_root);
+ DefaultMutableTreeNode app = new DefaultMutableTreeNode("Application WorkFlows");
+ DefaultMutableTreeNode views = new DefaultMutableTreeNode("Views");
+ root.add(app);
+ root.add(views);
+
+
+ app.add(new ActionTreeNode(_buyBook));
+ app.add(new ActionTreeNode(_deliver));
+ app.add(new ActionTreeNode(_supply));
+
+ views.add(new ActionTreeNode(_viewConfig));
+ views.add(new ActionTreeNode(_viewDomain));
+ views.add(new ActionTreeNode(_viewQuery));
+ views.add(new ActionTreeNode(_viewData));
+ views.add(new ActionTreeNode(_viewSource));
+
+
+ JTree tree = new JTree(root);
+ tree.setShowsRootHandles(true);
+
+ tree.addTreeSelectionListener(new TreeSelectionListener() {
+ public void valueChanged(TreeSelectionEvent e) {
+ Object treeNode = _navigator.getLastSelectedPathComponent();
+ if (treeNode instanceof ActionTreeNode) {
+ ((ActionTreeNode)treeNode)._action.actionPerformed(null);
+ }
+ }
+ });
+ tree.setCellRenderer(new TypedTreeCellRenderer());
+
+ return tree;
+ }
+
+ /**
+ * A tree node which may have an associated action.
+ *
+ * @author Pinaki Poddar
+ *
+ */
+ public static class ActionTreeNode extends DefaultMutableTreeNode {
+ private final Action _action;
+ public ActionTreeNode(Action action) {
+ _action = action;
+ }
+
+ public String toString() {
+ return _action.getValue(Action.SHORT_DESCRIPTION).toString();
+ }
+
+ }
+
+ public class TypedTreeCellRenderer extends DefaultTreeCellRenderer {
+ @Override
+ public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded,
+ boolean leaf, int row, boolean hasFocus) {
+ return super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);
+ }
+ }
+
+ public static class AboutDialog extends JDialog {
+ public AboutDialog(Icon logo) {
+ setModal(true);
+ setLayout(new BorderLayout());
+ JButton button = new JButton("<html>"
+ + "<b>OpenBooks</b> "
+ + "<br> using OpenJPA version " + OpenJPAVersion.MAJOR_RELEASE + "." + OpenJPAVersion.MINOR_RELEASE
+ + "<br> by JPA Team, SWG"
+ + "<br>IBM Corporation"
+ + "<p>"
+ + "</html>");
+ button.setIcon(logo);
+ button.setHorizontalTextPosition(SwingConstants.RIGHT);
+ button.setEnabled(true);
+ button.setBorderPainted(false);
+ add(button, BorderLayout.CENTER);
+ add(new JLabel(Images.getIcon("images/websphere.png")), BorderLayout.SOUTH);
+ setTitle("About OpenBooks");
+ setAlwaysOnTop(true);
+ setResizable(false);
+ pack();
+ }
+ }
+
+}
Propchange: openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/client/Demo.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/client/Images.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/client/Images.java?rev=944083&view=auto
==============================================================================
--- openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/client/Images.java (added)
+++ openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/client/Images.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 openbook.client;
+
+import java.awt.Image;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.swing.Icon;
+import javax.swing.ImageIcon;
+
+/**
+ * Utility to load and cache images.
+ *
+ * @author Pinaki Poddar
+ *
+ */
+public class Images {
+
+ private static Map<String, Icon> images = new HashMap<String, Icon>();
+ public static Icon NEXT = getIcon("images/nav_forward.gif");
+ public static Icon BACK = getIcon("images/nav_backward.gif");
+ public static Icon DONE = getIcon("images/done.png");
+ public static Icon CANCEL = getIcon("images/cancel.png");
+ public static Icon ERROR = getIcon("images/error.png");
+ public static Icon BROWSE = getIcon("images/browse.png");
+ public static Icon START = getIcon("images/start_task.gif");
+ public static Icon MONITOR = getIcon("images/console_view.gif");
+
+ public static Icon getIcon(String name) {
+ Icon icon = images.get(name);
+ if (icon == null) {
+ icon = createImageIcon(name);
+ images.put(name, icon);
+ }
+ return icon;
+ }
+
+ public static Icon getIcon(String name, boolean scale) {
+ return getIcon(name, 32, -1);
+ }
+
+ public static Icon getIcon(String name, int width, int height) {
+ Icon icon = getIcon(name);
+ if (icon == null) {
+ return null;
+ }
+ icon = new ImageIcon(((ImageIcon)icon).getImage().getScaledInstance(32, -1, Image.SCALE_SMOOTH));
+ return icon;
+ }
+
+ /**
+ * Returns an ImageIcon, or null if the path was invalid.
+ *
+ **/
+ protected static ImageIcon createImageIcon(String path) {
+ if (path == null)
+ return null;
+ URL imgURL = Thread.currentThread().getContextClassLoader().getResource(path);
+ if (imgURL != null) {
+ return new ImageIcon(imgURL);
+ } else {
+ imgURL = Images.class.getResource(path);
+ if (imgURL != null) {
+ return new ImageIcon(imgURL);
+ } else {
+ System.err.println("Couldn't find file: " + path);
+ return null;
+ }
+ }
+ }
+
+}
Propchange: openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/client/Images.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/client/SQLLogger.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/client/SQLLogger.java?rev=944083&view=auto
==============================================================================
--- openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/client/SQLLogger.java (added)
+++ openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/client/SQLLogger.java Fri May 14 02:14:30 2010
@@ -0,0 +1,70 @@
+/*
+ * 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 openbook.client;
+
+import java.awt.Color;
+import java.io.PrintStream;
+
+import javax.swing.SwingUtilities;
+import javax.swing.text.AttributeSet;
+import javax.swing.text.SimpleAttributeSet;
+import javax.swing.text.StyleConstants;
+import javax.swing.text.StyleContext;
+
+import jpa.tools.swing.GraphicOutputStream;
+
+
+
+import org.apache.openjpa.lib.jdbc.AbstractJDBCListener;
+import org.apache.openjpa.lib.jdbc.JDBCEvent;
+
+/**
+ * Logs SQL statement to a graphic console.
+ *
+ * @author Pinaki Poddar
+ *
+ */
+public class SQLLogger extends AbstractJDBCListener {
+ private static PrintStream out = null;
+ private static AttributeSet red, green, blue, magenta;
+ static {
+ StyleContext ctx = StyleContext.getDefaultStyleContext();
+ red = ctx.addAttribute(SimpleAttributeSet.EMPTY, StyleConstants.Foreground, Color.RED);
+ green = ctx.addAttribute(SimpleAttributeSet.EMPTY, StyleConstants.Foreground, Color.GREEN);
+ blue = ctx.addAttribute(SimpleAttributeSet.EMPTY, StyleConstants.Foreground, Color.BLUE);
+ magenta = ctx.addAttribute(SimpleAttributeSet.EMPTY, StyleConstants.Foreground, Color.MAGENTA);
+ }
+
+ public static void setOutput(GraphicOutputStream o) {
+ out = new PrintStream(o, true);
+ o.registerStyle("INSERT", green);
+ o.registerStyle("SELECT", blue);
+ o.registerStyle("UPDATE", magenta);
+ o.registerStyle("DELETE", red);
+ }
+
+ @Override
+ public void beforeExecuteStatement(final JDBCEvent event) {
+ if (out == null)
+ return;
+ SwingUtilities.invokeLater(new Runnable() {
+ public void run() {
+ out.println(event.getSQL());
+ }
+ });
+ }
+}
Propchange: openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/client/SQLLogger.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/client/SupplyPage.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/client/SupplyPage.java?rev=944083&view=auto
==============================================================================
--- openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/client/SupplyPage.java (added)
+++ openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/client/SupplyPage.java Fri May 14 02:14:30 2010
@@ -0,0 +1,140 @@
+/*
+ * 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 openbook.client;
+
+import java.awt.BorderLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import javax.swing.JButton;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.SwingWorker;
+
+import jpa.tools.swing.EntityDataModel;
+import jpa.tools.swing.EntityTableView;
+import jpa.tools.swing.ErrorDialog;
+import openbook.domain.Book;
+import openbook.domain.Inventory;
+import openbook.server.OpenBookService;
+
+/**
+ * A page to view and supply low inventory items.
+ *
+ * @author Pinaki Poddar
+ *
+ */
+@SuppressWarnings("serial")
+public class SupplyPage extends JPanel {
+ private final OpenBookService _service;
+
+ private final EntityTableView<Inventory> _lowInventories;
+
+ private final JButton _supply;
+ private final JButton _view;
+ private final JLabel _title;
+
+ private static int REORDER_LIMIT = 10;
+ private static int REORDER_QUANTITY = 40;
+
+ public SupplyPage(final OpenBookService service) {
+ setLayout(new BorderLayout());
+
+ _service = service;
+
+ _title = new JLabel(REORDER_LIMIT + " lowest inventory items");
+ _view = new JButton("Show " + REORDER_LIMIT + " lowest inventory items");
+ _supply = new JButton("Supply " + REORDER_QUANTITY + " to each item");
+
+ List<Inventory> orders = getInventory(REORDER_LIMIT);
+ _lowInventories = new EntityTableView<Inventory>(Inventory.class,
+ orders,
+ EntityDataModel.BASIC_ATTR | EntityDataModel.ASSOCIATION_ATTR,
+ service.getUnit());
+
+ add(_title, BorderLayout.NORTH);
+ add(_lowInventories, BorderLayout.CENTER);
+ JPanel buttons = new JPanel();
+ buttons.add(_view);
+ buttons.add(_supply);
+ add(buttons, BorderLayout.SOUTH);
+
+
+ _view.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ _lowInventories.getDataModel().updateData(getInventory(REORDER_LIMIT));
+ }
+ });
+
+ /**
+ * Supplies each inventory displayed.
+ */
+ _supply.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ new SwingWorker<List<Inventory>, Void>() {
+ @Override
+ protected List<Inventory> doInBackground() throws Exception {
+ EntityDataModel<Inventory> invs = _lowInventories.getDataModel();
+ List<Inventory> updated = new ArrayList<Inventory>();
+ for (Inventory inv : invs) {
+ Book supplied = _service.supply(inv.getBook(), REORDER_QUANTITY);
+ updated.add(supplied.getInventory());
+ }
+ return updated;
+ }
+
+ public void done() {
+ try {
+ _lowInventories.getDataModel().updateData(get(1, TimeUnit.SECONDS));
+ } catch (Exception e) {
+ new ErrorDialog(e).setVisible(true);
+ }
+ }
+ }.execute();
+
+ }
+
+ });
+ }
+
+ /**
+ * Gets the orders in a background (i.e. not AWT event dispatch thread) thread.
+ * <br>
+ * But blocks painting anyway, because that is what is intended.
+ *
+ */
+ private List<Inventory> getInventory(final Integer limit) {
+ SwingWorker<List<Inventory>, Void> worker = new SwingWorker<List<Inventory>, Void>() {
+ @Override
+ protected List<Inventory> doInBackground() throws Exception {
+ return _service.getReorderableBooks(REORDER_LIMIT);
+ }
+ };
+ worker.execute();
+ try {
+ return worker.get();
+ } catch (Exception e) {
+ new ErrorDialog(e).setVisible(true);
+ }
+ return Collections.emptyList();
+ }
+}
Propchange: openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/client/SupplyPage.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/Author.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/Author.java?rev=944083&view=auto
==============================================================================
--- openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/Author.java (added)
+++ openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/Author.java Fri May 14 02:14:30 2010
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2010 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 openbook.domain;
+
+
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.ManyToMany;
+import javax.persistence.Version;
+
+/**
+ * A persistent entity to represent an author of one or more Book.
+ * <br>
+ * <b>Notes</b>: No setter for identity value.
+ * <br>
+ * <LI><b>Identity</b>:Generated value as identity.
+ * <LI><b>Mapping</b>:Many-to-Many mapping to Books.
+ * <LI><b>Version</b>: Yes.
+ *
+ * @author Pinaki Poddar
+ *
+ */
+@Entity
+public class Author {
+ @Id
+ @GeneratedValue
+ private long id;
+
+ private String name;
+
+ @ManyToMany(mappedBy="authors")
+ private Set<Book> books;
+
+ @Version
+ private int version;
+
+ public long getId() {
+ return id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Set<Book> getBooks() {
+ return books;
+ }
+
+ public void addBook(Book book) {
+ if (books == null)
+ books = new HashSet<Book>();
+ books.add(book);
+ }
+
+ public int getVersion() {
+ return version;
+ }
+}
Propchange: openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/Author.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/Author_.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/Author_.java?rev=944083&view=auto
==============================================================================
--- openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/Author_.java (added)
+++ openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/Author_.java Fri May 14 02:14:30 2010
@@ -0,0 +1,19 @@
+/**
+ * Generated by OpenJPA MetaModel Generator Tool.
+**/
+
+package openbook.domain;
+
+import javax.persistence.metamodel.SetAttribute;
+import javax.persistence.metamodel.SingularAttribute;
+
+@javax.persistence.metamodel.StaticMetamodel
+(value=openbook.domain.Author.class)
+@javax.annotation.Generated
+(value="org.apache.openjpa.persistence.meta.AnnotationProcessor6",date="Thu May 13 20:18:23 CDT 2010")
+public class Author_ {
+ public static volatile SetAttribute<Author,Book> books;
+ public static volatile SingularAttribute<Author,Long> id;
+ public static volatile SingularAttribute<Author,String> name;
+ public static volatile SingularAttribute<Author,Integer> version;
+}
Propchange: openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/Author_.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/Book.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/Book.java?rev=944083&view=auto
==============================================================================
--- openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/Book.java (added)
+++ openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/Book.java Fri May 14 02:14:30 2010
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2010 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 openbook.domain;
+
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Id;
+import javax.persistence.ManyToMany;
+import javax.persistence.OneToOne;
+import javax.persistence.Version;
+
+/**
+ * An immutable persistent entity represents a Book.
+ * <br>
+ * The mutable properties of the book such as number of items in stock etc.
+ * are factored out in a separate {@link Inventory} instance.
+ * <br>
+ * The state of inventory is mutable, but the relation to inventory is immutable.
+ *
+ * <LI><b>Identity</b>: Application-defined identity.
+ * <LI><b>Mapping</b>: One-to-One bi-directional, immutable mapping to {@link Inventory}.
+ * Many-to-Many bi-directional mapping to {@linkplain Author}.
+ * <LI><b>Version</b>: No.
+ * <p>
+ *
+ * @author Pinaki Poddar
+ *
+ */
+@SuppressWarnings("serial")
+@Entity
+public class Book implements Serializable {
+ @Id
+ private String ISBN;
+
+ private String title;
+
+ private double price;
+
+ @OneToOne(mappedBy="book",
+ fetch=FetchType.LAZY,
+ cascade=CascadeType.ALL,
+ optional=false,
+ orphanRemoval=true)
+ private Inventory inventory;
+
+ @ManyToMany(fetch=FetchType.EAGER)
+ private List<Author> authors;
+
+ /**
+ * A no-arg constructor is required for JPA Specification.
+ */
+ public Book() {
+ }
+
+ /**
+ * Construct a book with given parameters.
+ *
+ * @param ISBN primary identity of this Book
+ * @param title Title of the book.
+ * @param price price of the book.
+ * @param initialSupply initial inventory quantity.
+ */
+ public Book(String ISBN, String title, double price, int initialSupply) {
+ this.ISBN = ISBN;
+ this.title = title;
+ this.price = price;
+ inventory = new Inventory(this, initialSupply);
+ }
+
+ public String getISBN() {
+ return ISBN;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public double getPrice() {
+ return price;
+ }
+
+ public List<Author> getAuthors() {
+ return authors;
+ }
+
+ public void addAuthor(Author...authors) {
+ if (this.authors == null)
+ this.authors = new ArrayList<Author>();
+ for (Author a : authors) {
+ if (!this.authors.contains(a))
+ this.authors.add(a);
+ }
+ }
+
+ public void setAuthors(List<Author> authors) {
+ this.authors = authors;
+ }
+
+ public Inventory getInventory() {
+ return inventory;
+ }
+
+ @Version
+ private int version;
+
+ public int getVersion() {
+ return version;
+ }
+}
Propchange: openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/Book.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/Book_.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/Book_.java?rev=944083&view=auto
==============================================================================
--- openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/Book_.java (added)
+++ openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/Book_.java Fri May 14 02:14:30 2010
@@ -0,0 +1,21 @@
+/**
+ * Generated by OpenJPA MetaModel Generator Tool.
+**/
+
+package openbook.domain;
+
+import javax.persistence.metamodel.ListAttribute;
+import javax.persistence.metamodel.SingularAttribute;
+
+@javax.persistence.metamodel.StaticMetamodel
+(value=openbook.domain.Book.class)
+@javax.annotation.Generated
+(value="org.apache.openjpa.persistence.meta.AnnotationProcessor6",date="Thu May 13 20:18:23 CDT 2010")
+public class Book_ {
+ public static volatile SingularAttribute<Book,String> ISBN;
+ public static volatile ListAttribute<Book,Author> authors;
+ public static volatile SingularAttribute<Book,Inventory> inventory;
+ public static volatile SingularAttribute<Book,Double> price;
+ public static volatile SingularAttribute<Book,String> title;
+ public static volatile SingularAttribute<Book,Integer> version;
+}
Propchange: openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/Book_.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/Customer.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/Customer.java?rev=944083&view=auto
==============================================================================
--- openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/Customer.java (added)
+++ openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/Customer.java Fri May 14 02:14:30 2010
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2010 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 openbook.domain;
+
+
+import java.io.Serializable;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.Version;
+
+/**
+ * A persistent entity represents a Customer.
+ *
+ * <br><b>Persistent Identity</b>: auto-generated identity.
+ * <br><b>Mapping</b>:
+ *
+ * <br><b>Design Notes</b>: No setter for identity value.
+ *
+ * @author Pinaki Poddar
+ *
+ */
+@SuppressWarnings("serial")
+@Entity
+public class Customer implements Serializable {
+ @Id
+ @GeneratedValue
+ private long id;
+ private String name;
+ private String email;
+
+ public Customer() {
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getEmail() {
+ return email;
+ }
+
+ public void setEmail(String email) {
+ this.email = email;
+ }
+
+ /**
+ * Create a {@link ShoppingCart} for this customer.
+ * @return
+ */
+ public ShoppingCart newCart() {
+ return new ShoppingCart(this);
+ }
+
+ @Version
+ private int version;
+
+ public int getVersion() {
+ return version;
+ }
+
+}
Propchange: openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/Customer.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/Customer_.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/Customer_.java?rev=944083&view=auto
==============================================================================
--- openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/Customer_.java (added)
+++ openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/Customer_.java Fri May 14 02:14:30 2010
@@ -0,0 +1,18 @@
+/**
+ * Generated by OpenJPA MetaModel Generator Tool.
+**/
+
+package openbook.domain;
+
+import javax.persistence.metamodel.SingularAttribute;
+
+@javax.persistence.metamodel.StaticMetamodel
+(value=openbook.domain.Customer.class)
+@javax.annotation.Generated
+(value="org.apache.openjpa.persistence.meta.AnnotationProcessor6",date="Thu May 13 20:18:23 CDT 2010")
+public class Customer_ {
+ public static volatile SingularAttribute<Customer,String> email;
+ public static volatile SingularAttribute<Customer,Long> id;
+ public static volatile SingularAttribute<Customer,String> name;
+ public static volatile SingularAttribute<Customer,Integer> version;
+}
Propchange: openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/Customer_.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/Inventory.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/Inventory.java?rev=944083&view=auto
==============================================================================
--- openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/Inventory.java (added)
+++ openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/Inventory.java Fri May 14 02:14:30 2010
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2010 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 openbook.domain;
+
+
+import java.io.Serializable;
+
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Id;
+import javax.persistence.OneToOne;
+import javax.persistence.Version;
+
+/**
+ * A mutable persistent entity.
+ *
+ * @author Pinaki Poddar
+ *
+ */
+@SuppressWarnings("serial")
+@Entity
+public class Inventory implements Serializable {
+ @Id
+ @OneToOne(fetch=FetchType.EAGER, optional=false)
+ private Book book;
+
+ private int supplied;
+
+ private int sold;
+
+ protected Inventory() {
+
+ }
+ /**
+ * Construct with the given Book and initial inventory count.
+ * Package protected because only a Book can create its own inventory.
+ *
+ * @param book non-null Book.
+ * @param initialSupply must be greater than zero.
+ */
+ Inventory(Book book, int initialSupply) {
+ if (book == null)
+ throw new NullPointerException("Can not create inventory for null Book");
+ if (initialSupply < 1)
+ throw new IllegalArgumentException("Can not create inventory " + initialSupply + " for " + book +
+ " Initial inventory must be greater than zero.");
+ this.book = book;
+ increment(initialSupply);
+ }
+
+ /**
+ * Gets the Book that this inventory represents.
+ *
+ * @return non-null Book.
+ */
+ public Book getBook() {
+ return book;
+ }
+
+ /**
+ * Gets the available quantity.
+ * This is an <em>in-flight</em> value representing the difference between the quantity supplied and quantity sold
+ * so far.
+ */
+ public int getInStock() {
+ return supplied - sold;
+ }
+
+ /**
+ * Gets the quantity supplied so far.
+ *
+ * @return a monotonically increasing positive number.
+ */
+ public int getSupplied() {
+ return supplied;
+ }
+
+ /**
+ * Gets the quantity sold so far.
+ *
+ * @return a monotonically increasing positive number.
+ */
+ public int getSold() {
+ return sold;
+ }
+
+ /**
+ * Increment this inventory by the given quantity.
+ *
+ * @param supplied must be positive.
+ */
+ public void increment(int supplied) {
+ if (supplied < 1)
+ throw new IllegalArgumentException("Can not add " + supplied + " supplies to " + this +
+ " Suuplied quanlity must be greater than zero.");
+ this.supplied += supplied;
+ }
+
+ /**
+ * Decrement this inventory by the given quantity.
+ *
+ * @param sold must be positive.
+ */
+ public void decrement(int sold) {
+ if (sold < 1)
+ throw new IllegalArgumentException("can not sell " + sold + "quantity to " + this
+ + "Sold quantity Must be greater than zero.");
+ this.sold += sold;
+ }
+
+ @Version
+ private int version;
+
+ public int getVersion() {
+ return version;
+ }
+
+}
Propchange: openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/Inventory.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/Inventory_.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/Inventory_.java?rev=944083&view=auto
==============================================================================
--- openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/Inventory_.java (added)
+++ openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/Inventory_.java Fri May 14 02:14:30 2010
@@ -0,0 +1,18 @@
+/**
+ * Generated by OpenJPA MetaModel Generator Tool.
+**/
+
+package openbook.domain;
+
+import javax.persistence.metamodel.SingularAttribute;
+
+@javax.persistence.metamodel.StaticMetamodel
+(value=openbook.domain.Inventory.class)
+@javax.annotation.Generated
+(value="org.apache.openjpa.persistence.meta.AnnotationProcessor6",date="Thu May 13 20:18:23 CDT 2010")
+public class Inventory_ {
+ public static volatile SingularAttribute<Inventory,Book> book;
+ public static volatile SingularAttribute<Inventory,Integer> sold;
+ public static volatile SingularAttribute<Inventory,Integer> supplied;
+ public static volatile SingularAttribute<Inventory,Integer> version;
+}
Propchange: openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/Inventory_.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/LineItem.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/LineItem.java?rev=944083&view=auto
==============================================================================
--- openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/LineItem.java (added)
+++ openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/LineItem.java Fri May 14 02:14:30 2010
@@ -0,0 +1,142 @@
+/*
+ * Copyright 2010 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 openbook.domain;
+
+
+import java.io.Serializable;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.IdClass;
+import javax.persistence.ManyToOne;
+import javax.persistence.OneToOne;
+import javax.persistence.OrderColumn;
+
+/**
+ * An immutable persistent entity with complex primary key.
+ * The primary key is combination of the primary identity of {@linkplain PurchaseOrder} and
+ * an 1-based integer index.
+ *
+ * @author Pinaki Poddar
+ *
+ */
+@SuppressWarnings("serial")
+@Entity
+@IdClass(LineItem.LineItemId.class)
+public class LineItem implements Serializable {
+ @Id
+ @OneToOne
+ private PurchaseOrder order;
+
+ @Id
+ @OrderColumn
+ @Column(name="IDX") // index is keyword
+ private int index;
+
+ @ManyToOne(optional=false)
+ private Book book;
+
+ private int quantity;
+
+ protected LineItem() {
+
+ }
+
+ /**
+ * Constructed as a line item for the given PurchaseOrder for the given Book for the given quantity.
+ * Package protected because only the PurchaseOrder can create its own LineItem.
+ *
+ * @param order non-null PurchaseOrder
+ * @param i the 1-based index of this line item in its parent PurchaseOrder
+ * @param book non-null Book of this line item
+ * @param quantity no. of books must be greater than zero.
+ */
+ LineItem(PurchaseOrder order, int i, Book book, int quantity) {
+ if (order == null)
+ throw new NullPointerException("Can not create LineItem for null PurchaseOrder");
+ if (i < 1)
+ throw new IllegalArgumentException("Can not create LineItem with index " + i + ". Must be > 0");
+ if (book == null)
+ throw new NullPointerException("Can not create LineItem for null Book");
+ if (quantity < 1)
+ throw new IllegalArgumentException("Can not create LineItem with quantity " + i + ". Must be > 0");
+
+ this.order = order;
+ this.index = i;
+ this.book = book;
+ this.quantity = quantity;
+ }
+
+ /**
+ * Gets the Book for this line item.
+ * @return non-null Book.
+ */
+ public Book getBook() {
+ return book;
+ }
+
+ /**
+ * Gets the quantity of the book for this line item.
+ * @return a positive number.
+ */
+ public int getQuantity() {
+ return quantity;
+ }
+
+ /**
+ * Gets the parent PurchaseOrder of this line item.
+ * @return non-null PurchaseOrder.
+ */
+ public PurchaseOrder getOrder() {
+ return order;
+ }
+
+ /**
+ * Gets the 1-based index this line item in its parent PurchaseOrder.
+ * @return index must be greater than zero.
+ */
+ public int getIndex() {
+ return index;
+ }
+
+ /**
+ * Separate identity class.
+ *
+ * @author Pinaki Poddar
+ *
+ */
+ public static class LineItemId implements Serializable {
+ long order;
+ int index;
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this)
+ return true;
+ if (other instanceof LineItemId) {
+ LineItemId that = (LineItemId)other;
+ return order == that.order && index == that.index;
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return (int) (31 ^ order + index);
+ }
+ }
+}
Propchange: openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/LineItem.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/LineItem_.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/LineItem_.java?rev=944083&view=auto
==============================================================================
--- openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/LineItem_.java (added)
+++ openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/LineItem_.java Fri May 14 02:14:30 2010
@@ -0,0 +1,18 @@
+/**
+ * Generated by OpenJPA MetaModel Generator Tool.
+**/
+
+package openbook.domain;
+
+import javax.persistence.metamodel.SingularAttribute;
+
+@javax.persistence.metamodel.StaticMetamodel
+(value=openbook.domain.LineItem.class)
+@javax.annotation.Generated
+(value="org.apache.openjpa.persistence.meta.AnnotationProcessor6",date="Thu May 13 20:18:23 CDT 2010")
+public class LineItem_ {
+ public static volatile SingularAttribute<LineItem,Book> book;
+ public static volatile SingularAttribute<LineItem,Integer> index;
+ public static volatile SingularAttribute<LineItem,PurchaseOrder> order;
+ public static volatile SingularAttribute<LineItem,Integer> quantity;
+}
Propchange: openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/LineItem_.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/PurchaseOrder.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/PurchaseOrder.java?rev=944083&view=auto
==============================================================================
--- openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/PurchaseOrder.java (added)
+++ openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/PurchaseOrder.java Fri May 14 02:14:30 2010
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2010 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 openbook.domain;
+
+
+import java.io.Serializable;
+import java.sql.Time;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.OneToMany;
+import javax.persistence.OneToOne;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+
+/**
+ * A persistent entity.
+ * Auto-generated identity.
+ * Enum and Date type persistent attribute.
+ * One-to-One uni-directional mapping to Customer.
+ * One-to-Many bi-directional mapping to LineItem.
+ *
+ * @author Pinaki Poddar
+ *
+ */
+@SuppressWarnings("serial")
+@Entity
+public class PurchaseOrder implements Serializable {
+ public enum Status {PENDING, DELEVERED};
+
+ @Id
+ @GeneratedValue
+ private long id;
+
+ @OneToOne(optional=false)
+ private Customer customer;
+
+ private Status status;
+
+ @OneToMany(mappedBy="order", cascade=CascadeType.ALL, orphanRemoval=true)
+ private List<LineItem> items;
+
+ private int total;
+
+ @Temporal(TemporalType.TIME)
+ private Date placedOn;
+
+ @Temporal(TemporalType.TIME)
+ private Date deliveredOn;
+
+ protected PurchaseOrder() {}
+
+ /**
+ * Constructed by transferring the content of the given {@linkplain ShoppingCart}.
+ * @param cart
+ */
+ public PurchaseOrder(ShoppingCart cart) {
+ customer = cart.getCustomer();
+ status = Status.PENDING;
+ placedOn = new Time(System.currentTimeMillis());
+ Map<Book, Integer> items = cart.getItems();
+ for (Map.Entry<Book, Integer> entry : items.entrySet()) {
+ addItem(entry.getKey(), entry.getValue());
+ }
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public Customer getCustomer() {
+ return customer;
+ }
+
+ public Status getStatus() {
+ return status;
+ }
+
+ public void setDelivered() {
+ if (this.status == Status.DELEVERED)
+ throw new IllegalStateException(this + " has been delivered");
+ this.status = Status.DELEVERED;
+ this.deliveredOn = new Time(System.currentTimeMillis());
+ }
+
+ public List<LineItem> getItems() {
+ return items;
+ }
+
+ void addItem(Book book, int quantity) {
+ if (items == null)
+ items = new ArrayList<LineItem>();
+ items.add(new LineItem(this, items.size()+1, book, quantity));
+ total += (book.getPrice() * quantity);
+ }
+
+ public double getTotal() {
+ return total;
+ }
+
+ public Date getPlacedOn() {
+ return placedOn;
+ }
+
+ public Date getDeliveredOn() {
+ return deliveredOn;
+ }
+}
Propchange: openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/PurchaseOrder.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/PurchaseOrder_.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/PurchaseOrder_.java?rev=944083&view=auto
==============================================================================
--- openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/PurchaseOrder_.java (added)
+++ openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/PurchaseOrder_.java Fri May 14 02:14:30 2010
@@ -0,0 +1,24 @@
+/**
+ * Generated by OpenJPA MetaModel Generator Tool.
+**/
+
+package openbook.domain;
+
+import java.util.Date;
+import javax.persistence.metamodel.ListAttribute;
+import javax.persistence.metamodel.SingularAttribute;
+import openbook.domain.PurchaseOrder.Status;
+
+@javax.persistence.metamodel.StaticMetamodel
+(value=openbook.domain.PurchaseOrder.class)
+@javax.annotation.Generated
+(value="org.apache.openjpa.persistence.meta.AnnotationProcessor6",date="Thu May 13 20:18:23 CDT 2010")
+public class PurchaseOrder_ {
+ public static volatile SingularAttribute<PurchaseOrder,Customer> customer;
+ public static volatile SingularAttribute<PurchaseOrder,Date> deliveredOn;
+ public static volatile SingularAttribute<PurchaseOrder,Long> id;
+ public static volatile ListAttribute<PurchaseOrder,LineItem> items;
+ public static volatile SingularAttribute<PurchaseOrder,Date> placedOn;
+ public static volatile SingularAttribute<PurchaseOrder,Status> status;
+ public static volatile SingularAttribute<PurchaseOrder,Integer> total;
+}
Propchange: openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/PurchaseOrder_.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/Range.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/Range.java?rev=944083&view=auto
==============================================================================
--- openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/Range.java (added)
+++ openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/Range.java Fri May 14 02:14:30 2010
@@ -0,0 +1,151 @@
+/*
+ * 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 openbook.domain;
+
+
+/**
+ * A simple numeric range.
+ * Minimum value is included, maximum value is excluded.
+ *
+ * @author Pinaki Poddar
+ *
+ */
+public class Range<N extends Number> {
+ private N min;
+ private N max;
+ private final Class<N> type;
+
+ public Range(Object min, Object max) {
+ this((N)min, (N)max);
+ }
+
+ /**
+ * Creates a range. Empty range i.e. where minimum equals maximum is allowed.
+ *
+ * @param min non-null minimum value.
+ * @param max non-null maximum value.
+ */
+ public Range(N min, N max) {
+ if (min == null || max == null)
+ throw new IllegalArgumentException("Supplied Min or Max is null");
+ if (max.doubleValue() < min.doubleValue())
+ throw new IllegalArgumentException("Invalid range (" + min + "," + max + ")");
+ this.min = min;
+ this.max = max;
+ type = (Class<N>)min.getClass();
+ }
+
+ public Class<N> type() {
+ return type;
+ }
+
+ /**
+ * Affirms if the given value is within this range.
+ * Minimum is included, maximum is excluded.
+ *
+ * @param x a non-null value
+ * @return true if the given value is greater than or equals to minimum and less than the maximum.
+ */
+ public boolean contains(Number x) {
+ return x != null && x.doubleValue() >= min.doubleValue() && x.doubleValue() < max.doubleValue();
+ }
+
+ /**
+ * Affirms if the given range is within this range.
+ * Minimum is included, maximum is excluded.
+ *
+ * @param x a non-null value
+ * @return true if the given value is greater than or equals to minimum and less than the maximum.
+ */
+ public <X extends Number> boolean contains(Range<X> r) {
+ return r != null && r.getMinimum().doubleValue() >= min.doubleValue() &&
+ r.getMaximum().doubleValue() <= max.doubleValue();
+ }
+
+ /**
+ * Gets the minimum value.
+ */
+ public N getMinimum() {
+ return min;
+ }
+
+ /**
+ * Gets the maximum value.
+ */
+ public N getMaximum() {
+ return max;
+ }
+
+ /**
+ * Adjusts this range by the given number.
+ *
+ * @param x a non-null value.
+ *
+ * @return if this range is adjusted by this value.
+ */
+ public boolean adjust(N x) {
+ if (x == null)
+ return false;
+ if (x.doubleValue() < min.doubleValue()) {
+ min = x;
+ return true;
+ }
+ if (x.doubleValue() > max.doubleValue()) {
+ max = x;
+ return true;
+ }
+ return false;
+ }
+
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((max == null) ? 0 : max.hashCode());
+ result = prime * result + ((min == null) ? 0 : min.hashCode());
+ result = prime * result + ((type == null) ? 0 : type.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ Range other = (Range) obj;
+ if (max == null) {
+ if (other.max != null)
+ return false;
+ } else if (!max.equals(other.max))
+ return false;
+ if (min == null) {
+ if (other.min != null)
+ return false;
+ } else if (!min.equals(other.min))
+ return false;
+ if (type == null) {
+ if (other.type != null)
+ return false;
+ } else if (!type.equals(other.type))
+ return false;
+ return true;
+ }
+}
Propchange: openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/Range.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/ShoppingCart.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/ShoppingCart.java?rev=944083&view=auto
==============================================================================
--- openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/ShoppingCart.java (added)
+++ openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/ShoppingCart.java Fri May 14 02:14:30 2010
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2010 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 openbook.domain;
+
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * A non-persistent entity holds the content of a shopping session for a {@linkplain Customer}.
+ * Used to create a persistent PurchaseOrder.
+ * Books can be added or removed from this cart.
+ *
+ * @author Pinaki Poddar
+ *
+ */
+@SuppressWarnings("serial")
+public class ShoppingCart implements Serializable {
+ private Customer customer;
+ private Map<Book, Integer> items;
+
+ /**
+ * Construct a cart for the given Customer.
+ *
+ * @param c non-null Customer.
+ */
+ ShoppingCart(Customer c) {
+ customer = c;
+ items = new HashMap<Book, Integer>();
+ }
+
+ /**
+ * Gets the Customer who owns this cart.
+ *
+ * @return non-null Customer.
+ */
+ public Customer getCustomer() {
+ return customer;
+ }
+
+ /**
+ * Gets the books with their corresponding quantity in this cart.
+ *
+ * @return
+ */
+ public Map<Book, Integer> getItems() {
+ return items;
+ }
+
+ /**
+ * Add the given book with the given quantity in the cart.
+ * If the book already exists then the quantity is added to the existing quantity.
+ *
+ * @param book non-null Book
+ * @param quantity a positive quantity.
+ */
+ public void addItem(Book book, int quantity) {
+ if (book == null)
+ throw new NullPointerException("Can not add null Book to " + this);
+ if (quantity < 1)
+ throw new IllegalArgumentException("Can not add " + quantity + " " + book + " to " + this +
+ " Added qunatity must be greater than zero");
+ int current = items.containsKey(book) ? items.get(book) : 0;
+ items.put(book, current + quantity);
+ }
+
+ /**
+ * Change the quantity of the given book by the given delta.
+ *
+ * @param book a non-null Book that must exist in this cart.
+ * @param delta no. of quantity to change. Can be positive or negative.
+ * If the resultant quantity becomes zero of negative, the book is removed from the cart.
+ */
+ public void changeQuantity(Book book, int delta) {
+ if (book == null)
+ throw new NullPointerException("Can not change quantity for null Book in " + this);
+ if (!items.containsKey(book))
+ throw new IllegalArgumentException("Can not change quantity for " + book + " becuase the book does not " +
+ "exist in " + this);
+ int current = items.containsKey(book) ? items.get(book) : 0;
+ if (current + delta <= 0) {
+ items.remove(book);
+ } else {
+ items.put(book, current + delta);
+ }
+ }
+
+ /**
+ * Removes the given book from this cart.
+ *
+ * @param book book a non-null Book that must exist in this cart.
+ */
+ public void remove(Book book) {
+ if (book == null)
+ throw new NullPointerException("Can not remove null Book from " + this);
+ if (!items.containsKey(book))
+ throw new IllegalArgumentException("Can not remove " + book + " becuase the book does not " +
+ "exist in " + this);
+ items.remove(book);
+ }
+
+ public void clear() {
+ items.clear();
+ }
+
+}
Propchange: openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/domain/ShoppingCart.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/server/OpenBookService.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/server/OpenBookService.java?rev=944083&view=auto
==============================================================================
--- openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/server/OpenBookService.java (added)
+++ openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/server/OpenBookService.java Fri May 14 02:14:30 2010
@@ -0,0 +1,181 @@
+/*
+ * Copyright 2010 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 openbook.server;
+
+import java.util.List;
+import java.util.Map;
+
+import javax.persistence.EntityManagerFactory;
+
+import openbook.domain.Book;
+import openbook.domain.Customer;
+import openbook.domain.Inventory;
+import openbook.domain.PurchaseOrder;
+import openbook.domain.ShoppingCart;
+
+/**
+ * A simple service to select Books, purchase them and manage their inventory.
+ * A service handle can be obtained from {@link ServiceFactory#getService(String)
+ * Service Factory}.
+ *
+ * @author Pinaki Poddar
+ *
+ */
+public interface OpenBookService {
+ public static final String DEFAULT_UNIT_NAME = "OpenBooks";
+
+ /**
+ * Starts a session for the given named Customer.
+ * If no record of the given name exists, a new Customer record is created.
+ *
+ * @param name name of a possibly existing customer. Or a new one.
+ *
+ * @return a Customer
+ */
+ public Customer login(String name);
+
+ /**
+ * Selects a list of Books matching the given conditions.
+ * Each of the conditional parameter can be null.
+ * A null parameter implies that the resultant query should ignore that parameter.
+ *
+ * @param title title of the Book
+ * @param min minimum price
+ * @param max maximum price
+ * @param author name of author
+ * @param decorators to modify the executable query such as its range.
+ * @return
+ */
+ public List<Book> select(String title,
+ Double min, Double max,
+ String author,
+ QueryDecorator...decorators);
+ /**
+ * Gets the query String for the given parameters.
+ * Each of the conditional parameter can be null.
+ * A null parameter implies that the resultant query should ignore that parameter.
+ *
+ * @param title title of the Book
+ * @param min minimum price
+ * @param max maximum price
+ * @param author name of author
+ * @param decorators to modify the executable query such as its range.
+ * @return
+ */
+ public String getQuery(String title,
+ Double min, Double max,
+ String author);
+
+ /**
+ * Runs an arbitrary JPQL query to return a list of result.
+ *
+ * @param jpql a valid JPQL query string.
+ * @param resultClass type of the result.
+ * @param decorators zero or more QueryDecorators to be applied before Query is executed.
+ * @return the selected instances.
+ */
+ <T> List<T> query(String jpql, Class<T> resultClass, QueryDecorator...decorators);
+ <T> List<T> getExtent(Class<T> entity);
+
+ /**
+ * Buys the content of the given cart.
+ *
+ * @param cart a non-empty cart.
+ * @return a PurchaseOrder for the content of the cart.
+ */
+ public PurchaseOrder placeOrder(ShoppingCart cart);
+
+ /**
+ * Delivers the given order. Delivery changes the status of the order, decrements
+ * inventory and finally removes the line items.
+ *
+ * @param order a PENDING order to be delivered.
+ * @return the PurchaseOrder after delivery.
+ *
+ */
+ public PurchaseOrder deliver(PurchaseOrder order);
+
+ /**
+ * Add inventory of the given Book by the given quantity.
+ *
+ * @param b a Book whose inventory is to be incremented
+ * @param quantity positive number.
+ *
+ * @return the Book after incrementing its inventory.
+ */
+ public Book supply(Book b, int quantity);
+
+ /**
+ * Gets the list of orders of given status.
+ *
+ * @param status status of the orders. null implies all orders.
+ *
+ * @return list of orders sorted by their placement dates.
+ */
+ public List<PurchaseOrder> getOrders(PurchaseOrder.Status status);
+
+
+ /**
+ * Gets the list of Books whose inventory is lower than the given limit.
+ *
+ * @param limit reorder limit. null implies all inventory.
+ *
+ * @return list of Books with inventory lower than the given limit.
+ */
+ public List<Inventory> getReorderableBooks(int limit);
+
+ /**
+ * Count the number of instances of the given persistent type.
+ *
+ * @param cls a persistent type.
+ * @return number of persistent entity of the given type.
+ */
+ public long count(Class<?> cls);
+
+ /**
+ * Populates the underlying data repository with sample values, only if
+ * the data repository is empty.
+ *
+ * @param loadParameters control the number of Books etc. to be created.
+ * null is allowed.
+ *
+ * @return true if the repository is initialized by this invocation.
+ */
+ public boolean initialize(Map<String,Object> loadParameters);
+ public void clean();
+ /**
+ * Gets the underlying persistence unit.
+ *
+ * @return
+ */
+ public EntityManagerFactory getUnit();
+
+ /**
+ * Gets the name of the underlying persistence unit.
+ *
+ * @return
+ */
+ public String getUnitName();
+
+ /**
+ * Affirms if the transaction on this persistence unit is managed by a container.
+ *
+ * @return
+ */
+ public boolean isManaged();
+
+
+}
Propchange: openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/server/OpenBookService.java
------------------------------------------------------------------------------
svn:eol-style = native