[Schmitzm-commits] r2285 - in trunk/schmitzm-hibernate/src/main: java/de/schmitzm/db/hibernate java/de/schmitzm/db/hibernate/gui java/de/schmitzm/db/hibernate/gui/event resources/de/schmitzm/db/hibernate/resource/locales
scm-commit at wald.intevation.org
scm-commit at wald.intevation.org
Mon Mar 25 22:10:30 CET 2013
Author: mojays
Date: 2013-03-25 22:10:30 +0100 (Mon, 25 Mar 2013)
New Revision: 2285
Added:
trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/
trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/DatabaseEntityTable.java
trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/DatabaseEntityTableModel.java
trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/DatabaseSearchQueryToolBar.java
trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/GUIUtil.java
trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/event/
trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/event/DatabaseRecordDeletedEvent.java
trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/event/DatabaseRecordUpdatedEvent.java
trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/event/DatabaseSearchListener.java
trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/event/DatabaseUpdateAdapter.java
trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/event/DatabaseUpdateEmitter.java
trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/event/DatabaseUpdateEvent.java
trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/event/DatabaseUpdateListener.java
Modified:
trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/DBUtil.java
trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/HibernateApplication.java
trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/HibernateSessionFactory.java
trunk/schmitzm-hibernate/src/main/resources/de/schmitzm/db/hibernate/resource/locales/HibernateResourceBundle.properties
trunk/schmitzm-hibernate/src/main/resources/de/schmitzm/db/hibernate/resource/locales/HibernateResourceBundle_de.properties
Log:
Global session removed from DBUtil; instead reference to static instance of HibernateSessionFactory
HibernateApplication: implementation of DatabaseUpdateEmitter
Several generic classes taken from WIME
Modified: trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/DBUtil.java
===================================================================
--- trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/DBUtil.java 2013-03-25 21:07:57 UTC (rev 2284)
+++ trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/DBUtil.java 2013-03-25 21:10:30 UTC (rev 2285)
@@ -1,12 +1,15 @@
package de.schmitzm.db.hibernate;
+import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import org.apache.log4j.Logger;
import org.hibernate.Criteria;
+import org.hibernate.JDBCException;
import org.hibernate.Session;
+import org.hibernate.Transaction;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
@@ -16,7 +19,7 @@
import de.schmitzm.db.hibernate.types.UniqueIDType;
import de.schmitzm.lang.LangUtil;
import de.schmitzm.lang.ResourceProvider;
-import de.schmitzm.swing.SwingUtil;
+import de.schmitzm.swing.ExceptionDialog;
/**
* Utility methods for hibernate.
@@ -27,46 +30,16 @@
private static Logger LOGGER = LangUtil.createLogger(DBUtil.class);
/**
- * {@link ResourceProvider} for the localization in the package
- * {@code de.schmitzm.db.hibernate}.
+ * Returns the global {@link Session} of the application wide {@link HibernateSessionFactory}
+ * instance. This session is used for internal/automatic database update, e.g. in
+ * {@link #getOrCreateBasicType(Class, String)}
*/
- public static ResourceProvider RESOURCE = ResourceProvider.newInstance(
- LangUtil.extendPackagePath(DBUtil.class,
- "resource.locales.HibernateResourceBundle"), Locale.ENGLISH);
+ public static Session getGlobalSession() {
+ final HibernateSessionFactory globalFactory = HibernateSessionFactory.getGlobalFactory();
+ return globalFactory.getSession();
+ }
/**
- * Can hold a global {@link Session} used for updates. Should never
- * be closed!
- */
- protected static Session GLOBAL_SESSION = null;
-
- /**
- * Returns the global {@link Session} which is used for internal/automatic
- * database update, e.g. in {@link #getOrCreateBasicType(Class, String)}
- * @param checkNull if {@code true} an exception is thrown if {@link #GLOBAL_SESSION}
- * is not set or closed.
- */
- public static Session getGlobalSession(boolean checkNull) {
- if ( checkNull ) {
- if ( GLOBAL_SESSION == null )
- throw new UnsupportedOperationException("DBUtil.GLOBAL_SESSION is not set.");
- if ( !GLOBAL_SESSION.isOpen() )
- throw new UnsupportedOperationException("DBUtil.GLOBAL_SESSION is not open.");
- if ( !GLOBAL_SESSION.isConnected() )
- throw new UnsupportedOperationException("DBUtil.GLOBAL_SESSION is not connected.");
- }
- return GLOBAL_SESSION;
- }
-
- /**
- * Sets the global {@link Session} which is used for internal/automatic
- * database update, e.g. in {@link #getOrCreateBasicType(Class, String)}
- */
- public static void setGlobalSession(Session session) {
- GLOBAL_SESSION = session;
- }
-
- /**
* Checks whether two objects represent the same record. The ID is
* used for compare.
*
@@ -141,11 +114,11 @@
/**
* Returns a {@link BasicTypeInterface} instance for the given description
- * or creates it if it does not exist. The {@linkplain #getGlobalSession(boolean) global session}
+ * or creates it if it does not exist. The {@linkplain #getGlobalSession() global session}
* is used for possible database updates.
* @param basicType basic type to determine the instance for
* @param desc description for the {@link BasicTypeInterface} instance
- * @see #getGlobalSession(boolean)
+ * @see #getGlobalSession()
*/
public static <E extends BasicTypeInterface> E getOrCreateBasicType(Class<E> basicType, String desc) {
return getOrCreateBasicType(basicType, desc, true);
@@ -153,7 +126,7 @@
/**
* Returns a {@link BasicTypeInterface} instance for the given description
- * or creates it if it does not exist. The {@linkplain #getGlobalSession(boolean) global session}
+ * or creates it if it does not exist. The {@linkplain #getGlobalSession() global session}
* is used for possible database updates.
* @param basicType basic type to determine the instance for
* @param desc description for the {@link BasicTypeInterface} instance
@@ -162,7 +135,7 @@
* creation). This has to be done explicitly later, e.g. in case when
* additional {@link BasicTypeInterface} attributes has to be
* filled before insert.
- * @see #getGlobalSession(boolean)
+ * @see #getGlobalSession()
*/
public static <E extends BasicTypeInterface> E getOrCreateBasicType(Class<E> basicType, String desc, boolean saveOrUpdate) {
return getOrCreateBasicType(null, basicType, desc, saveOrUpdate);
@@ -173,20 +146,20 @@
* or creates it if it does not exist.
* @param basicType basic type to determine the instance for
* @param session session to use for update (if {@code null} the
- * {@linkplain #getGlobalSession(boolean) global session} is used)
+ * {@linkplain #getGlobalSession() global session} is used)
* @param desc description for the {@link BasicTypeInterface} instance
* @param saveOrUpdate
* if {@code false}, no {@code Session.saveOrUpdate(.)} is performed (on possible
* creation). This has to be done explicitly later, e.g. in case when
* additional {@link BasicTypeInterface} attributes has to be
* filled before insert.
- * @see #getGlobalSession(boolean)
+ * @see #getGlobalSession()
*/
public static <E extends BasicTypeInterface> E getOrCreateBasicType(Session session, Class<E> basicType, String desc, boolean saveOrUpdate) {
if (org.apache.commons.lang.StringUtils.trimToNull(desc) == null)
return null;
if ( session == null )
- session = getGlobalSession(true);
+ session = getGlobalSession();
E instance = determineBasicType(basicType, desc);
if (instance == null) {
instance = createBasicTypeInstance(basicType);
@@ -201,7 +174,7 @@
* Checks whether a {@link BasicTypeInterface} instance is already persistent.
* If not it will be stored in database.
* @param session session to use for update (if {@code null} the
- * {@linkplain #getGlobalSession(boolean) global session} is used)
+ * {@linkplain #getGlobalSession() global session} is used)
* @param basicType basic type to check
* @return always {@code basicType}
*/
@@ -213,7 +186,7 @@
return basicType;
if ( session == null )
- session = getGlobalSession(true);
+ session = getGlobalSession();
session.persist(basicType);
return basicType;
@@ -222,7 +195,7 @@
/**
* Retrieves the first instances of a {@link BasicType} from database.
- * The {@linkplain #getGlobalSession(boolean) global session} is used
+ * The {@linkplain #getGlobalSession() global session} is used
* for database access.
* @param basicType basic type to determine an instance for
* @return {@code null} if the table is empty
@@ -237,7 +210,7 @@
/**
* Retrieves all instances of a type from database.
* @param session session to use for database access (if {@code null} the
- * {@linkplain #getGlobalSession(boolean) global session} is used)
+ * {@linkplain #getGlobalSession() global session} is used)
* @param type type to determine the instances for
*/
public static <E extends Object> List<E> determineAllRecords(Session session, Class<E> type) {
@@ -247,14 +220,14 @@
/**
* Retrieves all instances of a type from database, which satisfies a filter.
* @param session session to use for database access (if {@code null} the
- * {@linkplain #getGlobalSession(boolean) global session} is used)
+ * {@linkplain #getGlobalSession() global session} is used)
* @param type type to determine the instances for
* @param filter filter to apply
*/
public static <E extends Object> List<E> determineAllRecords(Session session, Class<E> type, Criterion filter, Order order) {
// if no session is specified, use the global session
if ( session == null )
- session = getGlobalSession(true);
+ session = getGlobalSession();
// Query muss in einer Transaktion erfolgen, damit die
// korrekten Daten ermittelt werden.
@@ -270,7 +243,7 @@
/**
* Retrieves all instances of a {@link BasicType} from database. The
- * {@linkplain #getGlobalSession(boolean) global session} is used for database access.
+ * {@linkplain #getGlobalSession() global session} is used for database access.
* @param basicType type to determine the instances for
*/
public static <E extends BasicTypeInterface> List<E> determineAllBasicTypes(Class<E> basicType) {
@@ -281,7 +254,7 @@
/**
* Retrieves all instances of a {@link BasicType} from database.
* @param session session to use for database access (if {@code null} the
- * {@linkplain #getGlobalSession(boolean) global session} is used)
+ * {@linkplain #getGlobalSession() global session} is used)
* @param basicType type to determine the instances for
*/
public static <E extends BasicTypeInterface> List<E> determineAllBasicTypes(Session session, Class<E> basicType) {
@@ -291,7 +264,7 @@
/**
* Retrieves all instances of a {@link BasicType} from database.
* @param session session to use for database access (if {@code null} the
- * {@linkplain #getGlobalSession(boolean) global session} is used)
+ * {@linkplain #getGlobalSession() global session} is used)
* @param basicType type to determine the instances for
* @param filter filter to apply
*/
@@ -301,11 +274,11 @@
/**
* Retrieves an instances of a {@link BasicType} from database with the specified description.
- * The {@linkplain #getGlobalSession(boolean) global session} is used for database access.
+ * The {@linkplain #getGlobalSession() global session} is used for database access.
*/
public static <E extends BasicTypeInterface> E determineBasicType(Class<E> basicType, String description) {
- Criteria query = getGlobalSession(true).createCriteria(basicType);
- query.add(Restrictions.eq("bezeichnung", description));
+ Criteria query = getGlobalSession().createCriteria(basicType);
+ query.add(Restrictions.eq(BasicType.DESCRIPTION_COL, description));
List<E> resultList = (List<E>) query.list();
if (resultList.isEmpty())
@@ -318,7 +291,7 @@
/**
* Retrieves the description of all {@link BasicType} instances from database.
- * The {@linkplain #getGlobalSession(boolean) global session} is used for database access.
+ * The {@linkplain #getGlobalSession() global session} is used for database access.
*/
public static <E extends BasicTypeInterface> List<String> determineAllBasicTypeDescriptions(Class<E> basicType) {
List<E> basicTypes = determineAllBasicTypes(basicType);
@@ -328,7 +301,23 @@
return basicTypeDesc;
}
- /**
+ /**
+ * Returns the name of the database table which represents the given type. This method expects that
+ * every type which represents a hibernate entity holds a static String field "TABLENAME".
+ */
+ public static String getDatabaseTable(Class<?> type) {
+ // TODO: Maybe we can use the annotation "Entity(name=...)" instead to retrieve the table name
+ try {
+ // Klassenname klappt irgenwie nicht !?
+ // return type.getSimpleName();
+ return (String) type.getDeclaredField("TABLENAME").get(null);
+ } catch (Exception err) {
+ throw new UnsupportedOperationException("Table name could not be retrieved from "
+ + LangUtil.getSimpleClassName(type), err);
+ }
+ }
+
+ /**
* Returns the name of the discriminator column for a given type. This method expects that the types which are
* define the shared table ("InheritanceType.SINGLE_TABLE") hold a static String field "DESCR_COLUMN".
*/
@@ -355,4 +344,75 @@
}
+ /**
+ * End the transaction of the global session.
+ * @param commit if {@code true} a COMMIT done, otherwise a ROLLBACK
+ * @return {@code false} if an error occurred
+ */
+ public static boolean endTransaction(boolean commit) {
+ return endTransaction(null, commit);
+ }
+
+ /**
+ * End the transaction of a session.
+ * @param commit if {@code true} a COMMIT done, otherwise a ROLLBACK
+ * @return {@code false} if an error occurred
+ */
+ public static boolean endTransaction(Session session, boolean commit) {
+ if ( session == null )
+ session = getGlobalSession();
+
+ Transaction transaction = session.getTransaction();
+ // Wenn keine Transaktion aktiv ist, nichts machen
+ if (transaction == null || !transaction.isActive())
+ return true;
+ try {
+ if (commit) {
+ // Transaktion durchfuehren
+ session.flush();
+ transaction.commit();
+ } else {
+ // Transaktion abbrechen
+ transaction.rollback();
+ // MS 26.10.2011: nicht ganz sicher, ob das sein muss!
+ // wenn drin, verhindert es, dass beim Abbrechen und erneutem
+ // Oeffnen des SeminarDataFrames ein eingefuegter, aber nicht
+ // gespeicherter Datensatz (Zombie) noch angezeigt wird!
+ // Dennoch: zuvor war es auskommentiert!?
+ session.clear();
+ }
+ return true;
+ } catch (Exception err) {
+ err = getNextException(err);
+ ExceptionDialog.show(err);
+ transaction.rollback();
+
+ return false;
+ } finally {
+ HibernateSessionFactory.beginTransactionIfNeeded(session);
+ }
+ }
+
+ /**
+ * If the given exception is a {@link JDBCException} the method returns
+ * {@code JDBCException.getSQLException().getNextException()} because its
+ * descriptions is more useful to show in {@link ExceptionDialog}.<br>
+ * Otherwise the methods returns the given {@link Exception} itself.
+ */
+ public static Exception getNextException(Exception err) {
+ // Wenn es sich um eine JDBCException handelt, deren
+ // Ausloeser anzeigen (aussagekraefitiger als die
+ // abgefangene Exception!)
+ if (err instanceof JDBCException) {
+ SQLException err2 = ((JDBCException) err).getSQLException();
+ if (err2 != null) {
+ err = err2;
+ if (err2.getNextException() != null)
+ err = err2.getNextException();
+ }
+ }
+ return err;
+
+ }
+
}
Modified: trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/HibernateApplication.java
===================================================================
--- trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/HibernateApplication.java 2013-03-25 21:07:57 UTC (rev 2284)
+++ trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/HibernateApplication.java 2013-03-25 21:10:30 UTC (rev 2285)
@@ -33,8 +33,8 @@
import javax.swing.JOptionPane;
-import org.apache.log4j.Logger;
-
+import de.schmitzm.db.hibernate.gui.GUIUtil;
+import de.schmitzm.db.hibernate.gui.event.DatabaseUpdateEmitter;
import de.schmitzm.swing.Disposable;
import de.schmitzm.swing.ExceptionDialog;
import de.schmitzm.swing.SwingUtil;
@@ -50,7 +50,7 @@
* the database.
* @author Martin O.J. Schmitz
*/
-public abstract class HibernateApplication implements Disposable {
+public abstract class HibernateApplication extends DatabaseUpdateEmitter implements Disposable {
/** Holds the {@link HibernateSessionFactory} which handles the
* database connection via hibernate. */
@@ -162,8 +162,8 @@
boolean ret = connectToDatabase(true);
if (ret)
JOptionPane.showMessageDialog(getMainFrame(),
- DBUtil.RESOURCE.getString("HibernateApplication.db.init.confirm.mess"),
- DBUtil.RESOURCE.getString("HibernateApplication.db.init.title"),
+ GUIUtil.R("HibernateApplication.db.init.confirm.mess"),
+ GUIUtil.R("HibernateApplication.db.init.title"),
JOptionPane.INFORMATION_MESSAGE);
return ret;
}
@@ -206,7 +206,7 @@
try {
Object[] optionValues = MultipleOptionPane.showMultipleInputDialog(
getMainFrame(),
- DBUtil.RESOURCE.getString("HibernateApplication.db.conn.dialog.title"),
+ GUIUtil.R("HibernateApplication.db.conn.dialog.title"),
dbConnectOptions);
if (optionValues == null) {
// clear Password for security reasons
@@ -214,9 +214,10 @@
return false;
}
if (forceCreate) {
- int ret = JOptionPane.showConfirmDialog(getMainFrame(),
- DBUtil.RESOURCE.getString("HibernateApplication.db.init.warn.mess"),
- DBUtil.RESOURCE.getString("HibernateApplication.db.init.title"),
+ int ret = JOptionPane.showConfirmDialog(
+ getMainFrame(),
+ GUIUtil.R("HibernateApplication.db.init.warn.mess"),
+ GUIUtil.R("HibernateApplication.db.init.title"),
JOptionPane.YES_NO_OPTION);
if (ret != JOptionPane.YES_OPTION) {
dbConnectOptions[4].setValue(null);
@@ -251,7 +252,7 @@
};
SwingWorker worker = new SwingWorker(connectionWork,
getMainFrame(),
- DBUtil.RESOURCE.getString("HibernateApplication.db.conn.progress.mess"),
+ GUIUtil.R("HibernateApplication.db.conn.progress.mess"),
0.5, 0.5);
// worker.getDialog().setDialogOption(StatusDialog.NONE_OPTION);
worker.start();
@@ -277,6 +278,7 @@
handleConnectionException(err);
}
+ fireDatabaseConnectionEstablished();
return true;
}
@@ -290,6 +292,8 @@
return false;
sessionFactory.disconnectAllSessions();
sessionFactory.killSessionFactory();
+
+ fireDatabaseConnectionReleased();
return true;
}
Modified: trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/HibernateSessionFactory.java
===================================================================
--- trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/HibernateSessionFactory.java 2013-03-25 21:07:57 UTC (rev 2284)
+++ trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/HibernateSessionFactory.java 2013-03-25 21:10:30 UTC (rev 2285)
@@ -1,6 +1,5 @@
package de.schmitzm.db.hibernate;
-import java.io.File;
import java.io.Serializable;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
@@ -18,18 +17,18 @@
import org.hibernate.cfg.Environment;
import org.hibernate.jdbc.Work;
-import de.schmitzm.io.IOUtil;
import de.schmitzm.lang.LangUtil;
-import de.schmitzm.versionnumber.ReleaseControl;
-import de.schmitzm.versionnumber.ReleaseUpdater;
/**
* Configures and provides access to Hibernate sessions, tied to the current thread of execution. Follows the Thread
* Local Session pattern, see {@link http://hibernate.org/42.html }.
*/
public abstract class HibernateSessionFactory {
- private Logger LOGGER = LangUtil.createLogger(this);
+ private static Logger LOGGER = LangUtil.createLogger(HibernateSessionFactory.class);
+ /** Application wide instance of {@link HibernateSessionFactory}. */
+ private static HibernateSessionFactory INST;
+
private Session globalSession = null;
private Map<Object,Session> sessions = new HashMap<Object,Session>();
@@ -65,18 +64,42 @@
public HibernateSessionFactory(boolean multipleSessions, String configFile) {
this.MULTIPLE_SESSIONS = multipleSessions;
this.configFile = configFile;
+ setGlobalInstance(this);
}
-// /**
-// * return session factory
-// *
-// * session factory will be rebuilded in the next call
-// */
-// public static void setConfigFile(String configFile) {
-// sessionFactory = null;
-// }
+ /**
+ * Returns the application wide instance of {@link HibernateSessionFactory}.
+ * @param checkNull if {@code true} an exception is thrown if {@link #INST}
+ * is not set yet or not connected.
+ */
+ public static HibernateSessionFactory getGlobalFactory(boolean checkNull) {
+ if ( checkNull ) {
+ if ( INST == null )
+ throw new UnsupportedOperationException("No instance of "+LangUtil.getSimpleClassName(HibernateSessionFactory.class)+" created yet!");
+ if ( !INST.isConnected() )
+ throw new UnsupportedOperationException("Global instance of "+LangUtil.getSimpleClassName(HibernateSessionFactory.class)+" is not connected!");
+ }
+ return INST;
+ }
+
+ /**
+ * Returns the application wide instance of {@link HibernateSessionFactory}.
+ */
+ public static HibernateSessionFactory getGlobalFactory() {
+ return getGlobalFactory(true);
+ }
/**
+ * Sets the application wide {@link HibernateSessionFactory} instance.
+ * Should only be called by constructor.
+ */
+ protected static void setGlobalInstance(HibernateSessionFactory factory) {
+ if ( INST != null && factory != null )
+ LOGGER.warn(LangUtil.getSimpleClassName(HibernateSessionFactory.class)+".setGlobalInstance(.) called twice! Application wide instance should one be set once!");
+ INST = factory;
+ }
+
+ /**
* return hibernate configuration
*
*/
@@ -334,7 +357,7 @@
* transaction end (<b>Note:</b> it depends on the database and version, which constraints are effected
* by the <i>deferred</i> setting!!)
*/
- private void beginTransactionIfNeeded(Session session, boolean deferredChecks) {
+ private static void beginTransactionIfNeeded(Session session, boolean deferredChecks) {
if (session == null)
throw new UnsupportedOperationException(
"Transaktion kann nicht begonnen werden, da keine Session zur Verfuegung steht!");
@@ -363,7 +386,7 @@
/**
* Starts a new transaction with immediate constraint checking.
*/
- public void beginTransactionIfNeeded(Session session) {
+ public static void beginTransactionIfNeeded(Session session) {
beginTransactionIfNeeded(session,false);
}
Added: trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/DatabaseEntityTable.java
===================================================================
--- trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/DatabaseEntityTable.java (rev 0)
+++ trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/DatabaseEntityTable.java 2013-03-25 21:10:30 UTC (rev 2285)
@@ -0,0 +1,90 @@
+package de.schmitzm.db.hibernate.gui;
+
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.util.List;
+import java.util.Vector;
+
+import javax.swing.ListSelectionModel;
+
+import de.schmitzm.db.hibernate.types.UniqueIDType;
+import de.schmitzm.swing.SortableJTable;
+
+/**
+ * Panel, which shows a list of database records of one table.
+ * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a>
+ */
+public class DatabaseEntityTable<E extends UniqueIDType> extends SortableJTable {
+ /**
+ * Creates a new panel.
+ */
+ public DatabaseEntityTable(DatabaseEntityTableModel<E> tableModel) {
+ super(tableModel);
+ initGUI();
+ }
+
+ /**
+ * Initalises the GUI components.
+ */
+ protected void initGUI() {
+ setAutoGrowColums(true);
+ setSelectionMode( ListSelectionModel.SINGLE_SELECTION );
+ addMouseListener( new MouseAdapter() {
+ public void mouseClicked(MouseEvent e) {
+ // nur auf Doppelklick reagieren
+ if ( e.getClickCount() < 2 || e.getButton() != e.BUTTON1 )
+ return;
+
+ E selectedEntity = getSelectedEntity();
+ if ( selectedEntity == null )
+ return;
+ performEntitySelection(selectedEntity);
+ }
+ });
+ }
+
+ /**
+ * Returns the table model.
+ */
+ @Override
+ public DatabaseEntityTableModel<E> getModel() {
+ return (DatabaseEntityTableModel<E>)super.getModel();
+ }
+
+ /**
+ * Returns the entity which currently is selected in table.
+ */
+ public E getSelectedEntity() {
+ int selectedModelRow = getSelectedModelRow();
+ if ( selectedModelRow < 0 )
+ return null;
+ return getModel().getEntity(selectedModelRow);
+ }
+
+ /**
+ * Returns all entities currently selected in table.
+ */
+ public List<E> getSelectedEntities() {
+ int[] selectedModelRows = getSelectedModelRows();
+ List<E> selectedKontakte = new Vector<E>();
+ for (int selectedModelRow : selectedModelRows)
+ selectedKontakte.add( getModel().getEntity(selectedModelRow) );
+ return selectedKontakte;
+ }
+
+ /**
+ * Returns all entities currently displayed in table.
+ */
+ public List<E> getEntities() {
+ return getModel().getEntities();
+ }
+
+ /**
+ * Reacts on double click on a table row.
+ * This method does nothing. Sub-classes can override this method
+ * to implement a special functionality.
+ */
+ protected void performEntitySelection(E kontakt) {
+ }
+
+}
\ No newline at end of file
Added: trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/DatabaseEntityTableModel.java
===================================================================
--- trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/DatabaseEntityTableModel.java (rev 0)
+++ trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/DatabaseEntityTableModel.java 2013-03-25 21:10:30 UTC (rev 2285)
@@ -0,0 +1,180 @@
+package de.schmitzm.db.hibernate.gui;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.swing.table.TableModel;
+
+import de.schmitzm.db.hibernate.DBUtil;
+import de.schmitzm.db.hibernate.HibernateSessionFactory;
+import de.schmitzm.db.hibernate.gui.event.DatabaseRecordDeletedEvent;
+import de.schmitzm.db.hibernate.gui.event.DatabaseUpdateEmitter;
+import de.schmitzm.db.hibernate.gui.event.DatabaseUpdateEvent;
+import de.schmitzm.db.hibernate.gui.event.DatabaseUpdateListener;
+import de.schmitzm.db.hibernate.types.UniqueIDType;
+import de.schmitzm.swing.Disposable;
+import de.schmitzm.swing.table.AbstractTableModel;
+
+/**
+ * Read-only {@link TableModel} for the content of a database table.
+ * Because only read-access is needed to update records in table,
+ * the {@linkplain DBUtil#getGlobalSession() global session} is
+ * used for database access. The application has ensure that an instance of
+ * {@link HibernateSessionFactory} is already created to provide this global
+ * session.
+ * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a>
+ *
+ */
+public abstract class DatabaseEntityTableModel<E extends UniqueIDType> extends AbstractTableModel implements DatabaseUpdateListener, Disposable {
+ private boolean disposed = false;
+
+ /** Holds the entities */
+ protected List<E> entities = new ArrayList<E>();
+ /** Holds the {@link DatabaseUpdateEmitter} which informs the table about
+ * database changes. */
+ protected DatabaseUpdateEmitter dbUpdateEmitter = null;
+
+ /**
+ * Creates a new table model.
+ * @param updateEmitter emitter which informs the table about database changes
+ * @param entities initial data
+ */
+ public DatabaseEntityTableModel(DatabaseUpdateEmitter updateEmitter, List<E> entities) {
+ super();
+ if ( entities == null )
+ entities = new ArrayList<E>();
+ this.entities = entities;
+ this.dbUpdateEmitter = updateEmitter;
+ if ( updateEmitter != null )
+ updateEmitter.addDatabaseUpdateListener(this);
+ }
+
+ /**
+ * Creates an empty table model.
+ * @param updateEmitter emitter which informs the table about database changes
+ */
+ public DatabaseEntityTableModel(DatabaseUpdateEmitter updateEmitter) {
+ this(updateEmitter,null);
+ }
+
+ /**
+ * Sets the data of the table.
+ */
+ public void setEntities(List<E> entities) {
+ this.entities = entities;
+ fireTableDataChanged();
+ }
+
+ /**
+ * Returns the data of the table.
+ */
+ public List<E> getEntities() {
+ return entities;
+ }
+
+ /**
+ * Returns on entity of the table.
+ */
+ public E getEntity(int row) {
+ return entities.get(row);
+ }
+
+ /**
+ * Returns the number of (displayed) entities in the table.
+ */
+ @Override
+ public int getRowCount() {
+ if ( entities == null )
+ return 0;
+ return entities.size();
+ }
+
+ /**
+ * Always returns {@code false}.
+ */
+ @Override
+ public boolean isCellEditable(int row, int col) {
+ return false;
+ }
+
+ /**
+ * Clears the list.
+ */
+ public void clear() {
+ entities.clear();
+ fireTableDataChanged();
+ }
+
+ /**
+ * Returns the column type for a table column (table attribute).
+ */
+ @Override
+ public abstract Class getColumnClass(int col);
+
+ /**
+ * Returns an entity attribute value.
+ */
+ @Override
+ public abstract Object getValueAt(int row, int col);
+
+ /**
+ * Returns the attribute names for the table.
+ */
+ @Override
+ public abstract String[] createColumnNames();
+
+ /**
+ * If the updated entity is an instance of {@code E} and it is
+ * displayed in table, the record is updated from database (using
+ * {@link DBUtil#getGlobalSession()}!!) and renewed in {@link TableModel}.
+ * If the event is a {@link DatabaseRecordDeletedEvent} the entity is removed
+ * from {@link TableModel}.
+ */
+ @Override
+ public void databaseUpdated(DatabaseUpdateEvent e) {
+ if ( entities == null )
+ return;
+ if ( !entities.contains(e.getUpdatedRecord()) )
+ return;
+
+ int row = entities.indexOf( e.getUpdatedRecord() );
+ if (e instanceof DatabaseRecordDeletedEvent){
+ entities.remove(row);
+ fireTableRowsDeleted(row, row);
+ } else {
+ E updatedRecord = (E)e.getUpdatedRecord();
+ int id = updatedRecord.getId();
+ updatedRecord = (E)DBUtil.getGlobalSession().get(updatedRecord.getClass(), id);
+ DBUtil.getGlobalSession().evict(updatedRecord);
+ entities.set(row,updatedRecord);
+ fireTableRowsUpdated(row, row);
+ }
+ }
+
+ /**
+ * Clears the table model if the connection was closed.
+ */
+ @Override
+ public void databaseConnectionStateChanged(boolean connected) {
+ if ( !connected )
+ setEntities(null);
+ }
+
+ /**
+ * Removes the {@link DatabaseUpdateListener} from {@link DatabaseUpdateEmitter}.
+ */
+ @Override
+ public void dispose() {
+ if ( dbUpdateEmitter != null )
+ dbUpdateEmitter.removeDatabaseUpdateListener(this);
+ this.disposed = true;
+ }
+
+ /**
+ * Prueft, ob das Datenmodell noch aktiv ist.
+ * @return
+ */
+ public boolean isDisposed() {
+ return disposed;
+ }
+}
\ No newline at end of file
Added: trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/DatabaseSearchQueryToolBar.java
===================================================================
--- trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/DatabaseSearchQueryToolBar.java (rev 0)
+++ trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/DatabaseSearchQueryToolBar.java 2013-03-25 21:10:30 UTC (rev 2285)
@@ -0,0 +1,156 @@
+package de.schmitzm.db.hibernate.gui;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.swing.Action;
+import javax.swing.JButton;
+import javax.swing.JComboBox;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JToolBar;
+import javax.swing.RootPaneContainer;
+
+import org.apache.commons.lang.StringUtils;
+
+import net.miginfocom.swing.MigLayout;
+import de.schmitzm.db.hibernate.DBUtil;
+import de.schmitzm.db.hibernate.gui.event.DatabaseSearchListener;
+import de.schmitzm.db.hibernate.gui.event.DatabaseUpdateEmitter;
+import de.schmitzm.db.hibernate.gui.event.DatabaseUpdateEvent;
+import de.schmitzm.db.hibernate.gui.event.DatabaseUpdateListener;
+import de.schmitzm.swing.GUIBuilder;
+import de.schmitzm.swing.SwingUtil;
+
+/**
+ * Panel to specify the search query. To update the GUI fields automatically
+ * when database connection is established or closed, this class should added
+ * as {@link DatabaseUpdateListener} to the {@link DatabaseUpdateEmitter} of
+ * the application.
+ * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a>
+ */
+public abstract class DatabaseSearchQueryToolBar<E> extends JToolBar implements DatabaseUpdateListener {
+ protected JButton searchButton;
+ protected JLabel queryLabel;
+ protected JComboBox<String> queryComboBox;
+
+ protected ActionListener searchActionListener;
+ protected Action searchAction;
+
+ /** Lis of listeners, which react on search query results. */
+ protected List<DatabaseSearchListener<E>> resultListeners = new ArrayList<DatabaseSearchListener<E>>();
+
+ /**
+ * Creates a new panel.
+ */
+ public DatabaseSearchQueryToolBar() {
+ super();
+ setFloatable(false);
+ setLayout( new MigLayout("","0[][][]","center") );
+
+ queryLabel = GUIBuilder.INST.createHeaderLabel(GUIUtil.R("DatabaseSearchQueryToolBar.Query"));
+ queryComboBox = new JComboBox<String>();
+ queryComboBox.setEditable(true);
+
+ searchActionListener = new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ String pattern = getQueryPattern();
+ // Wenn das Pattern noch nicht in der Liste enthalten ist,
+ // der Combobox-Auswahl hinzufuegen
+ if ( queryComboBox.getSelectedIndex() < 0 && !StringUtils.isBlank(pattern) )
+ queryComboBox.insertItemAt(pattern, 0);
+
+ performSearch();
+ }
+ };
+ searchAction = GUIBuilder.INST.createAction(GUIUtil.R("DatabaseSearchQueryToolBar.SEARCH"),
+ searchActionListener,
+ "SEARCH",
+ GUIUtil.R("DatabaseSearchQueryToolBar.SEARCH.desc"),
+ GUIUtil.ICON_SEARCH);
+ searchButton = new JButton(searchAction);
+
+ add(queryLabel,"");
+ add(queryComboBox,"w 100:200, growx");
+ add(searchButton,"span 1 2");
+ addSeparator();
+
+ // Update actions as no connection is established yet
+ databaseConnectionStateChanged(false);
+ }
+
+ /**
+ * Sets the Search-button as default button for RETURN key.
+ */
+ public void setSearchButtonToDefaultAction(RootPaneContainer frame) {
+ frame.getRootPane().setDefaultButton(searchButton);
+ }
+
+ /**
+ * Performs the search query and informs the connected listeners by
+ * {@link #fireSearchResult(List)}.
+ */
+ protected abstract void performSearch();
+
+ /**
+ * Returns the query pattern specified in editable {@link JComboBox}.
+ */
+ public String getQueryPattern() {
+ String pattern = queryComboBox.getSelectedItem() != null ? queryComboBox.getSelectedItem().toString() : "";
+ return pattern;
+ }
+
+ /**
+ * Informs all connected {@link DatabaseSearchListener} about the new search
+ * result.
+ * @param result search result
+ */
+ protected void fireSearchResult(List<E> result) {
+ String pattern = getQueryPattern();
+ for (DatabaseSearchListener<E> l : resultListeners)
+ l.performSeachResult(pattern,result);
+ }
+
+ /**
+ * Adds a listener. Each {@link DatabaseSearchListener} can only be added once.
+ * @return {@code true} if the listener was added successfully
+ */
+ public boolean addSearchListener(DatabaseSearchListener<E> l) {
+ if ( resultListeners.contains(l) )
+ return false;
+ return resultListeners.add(l);
+ }
+
+ /**
+ * Removes a listener.
+ */
+ public boolean removeSearchUpdateListener(DatabaseSearchListener<E> l) {
+ return resultListeners.remove(l);
+ }
+
+ /**
+ * Returns all listeners.
+ */
+ public List<DatabaseSearchListener<E>> getSearchListeners() {
+ return resultListeners;
+ }
+
+ /**
+ * Does nothing.
+ */
+ @Override
+ public void databaseUpdated(DatabaseUpdateEvent e) {
+ }
+
+ /**
+ * Updates the actions in panel.
+ */
+ @Override
+ public void databaseConnectionStateChanged(boolean connected) {
+ searchButton.setEnabled(connected);
+ }
+
+}
Added: trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/GUIUtil.java
===================================================================
--- trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/GUIUtil.java (rev 0)
+++ trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/GUIUtil.java 2013-03-25 21:10:30 UTC (rev 2285)
@@ -0,0 +1,135 @@
+/**
+ * Copyright (c) 2009 Martin O. J. Schmitz.
+ *
+ * This file is part of the SCHMITZM library - a collection of utility
+ * classes based on Java 1.6, focusing (not only) on Java Swing
+ * and the Geotools library.
+ *
+ * The SCHMITZM project is hosted at:
+ * http://wald.intevation.org/projects/schmitzm/
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License (license.txt)
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * or try this link: http://www.gnu.org/licenses/lgpl.html
+ *
+ * Contributors:
+ * Martin O. J. Schmitz - initial API and implementation
+ * Stefan A. Tzeggai - additional utility classes
+ */
+package de.schmitzm.db.hibernate.gui;
+
+import java.awt.Component;
+import java.util.Locale;
+
+import javax.swing.ImageIcon;
+import javax.swing.JOptionPane;
+
+import org.hibernate.Session;
+import org.hibernate.Transaction;
+
+import de.schmitzm.db.hibernate.DBUtil;
+import de.schmitzm.lang.LangUtil;
+import de.schmitzm.lang.ResourceProvider;
+import de.schmitzm.swing.SwingUtil;
+
+/**
+ * Utility GUI method for working with Hibernate.
+ * @author Martin O.J. Schmitz
+ *
+ */
+public class GUIUtil {
+ /** Icon for "SEARCH" button. */
+ public static final ImageIcon ICON_SEARCH = SwingUtil.createImageIconFromResourcePath("resource/icons/small/zoom.png", null);
+
+ /**
+ * {@link ResourceProvider} for the localization in the package
+ * {@code de.schmitzm.db.hibernate}.
+ */
+ public static ResourceProvider RESOURCE = ResourceProvider.newInstance(
+ LangUtil.extendPackagePath(DBUtil.class,
+ "resource.locales.HibernateResourceBundle"), Locale.ENGLISH);
+ /**
+ * Shortcut for {@code RESOURCE.getString(..)}.
+ */
+ public static String R(String key, Object... values) {
+ return RESOURCE.getString(key, values);
+ }
+
+ /**
+ * Shows a dialog to confirm the database update.
+ * @return {@link JOptionPane#YES_OPTION}, {@link JOptionPane#CANCEL_OPTION}
+ * oder {@link JOptionPane#NO_OPTION}
+ */
+ public static int confirmSaveMessage(Component parent) {
+ int confirm = JOptionPane.showConfirmDialog(
+ parent,
+ R("GUIUtil.save.confirm.mess"),
+ R("GUIUtil.save.confirm.mess.title"),
+ JOptionPane.YES_NO_CANCEL_OPTION);
+ return confirm;
+ }
+
+ /**
+ * Ends the current transaction (of the global session). If not persistent changes
+ * exist the user is asked whether the changes should be committed or aborted.
+ * @param parent parent component for comfirm dialog
+ * @return {@code false} if the dialog was canceled or in case of errors;
+ * {@code true} if transaction was ended correctly (commit or rollback)
+ * or if there are not changes to commit
+ */
+ public static boolean confirmTransactionEnd(Component parent) {
+ return confirmTransactionEnd(parent, null);
+ }
+
+ /**
+ * Ends the current transaction of a session. If not persistent changes
+ * exist the user is asked whether the changes should be committed or aborted.
+ * @param parent parent component for comfirm dialog
+ * @return {@code false} if the dialog was canceled or in case of errors;
+ * {@code true} if transaction was ended correctly (commit or rollback)
+ * or if there are not changes to commit
+ */
+ public static boolean confirmTransactionEnd(Component parent, Session session) {
+ if ( session == null )
+ session = DBUtil.getGlobalSession();
+ Transaction transaction = session.getTransaction();
+ // Wenn keine Transaktion aktiv ist, nichts machen
+ if (transaction == null || !transaction.isActive())
+ return true;
+ // Wenn keine Aenderungen vorliegen, Transaktion abbrechen
+ // und weiter nichts machen
+ if (!session.isDirty()) {
+ DBUtil.endTransaction(session,false);
+ return true;
+ }
+
+ // Speichern der Aenderungen bestaetigen lassen
+ int confirm = confirmSaveMessage(parent);
+ switch (confirm) {
+ case JOptionPane.CANCEL_OPTION: // Abbrechen
+ case JOptionPane.CLOSED_OPTION: // "Kreuzchen" des Dialogs oder ESC
+ // -> Nichts machen und zur letzzen Aktion zurueck kehren
+ return false;
+ case JOptionPane.NO_OPTION:
+ // Transaktion abbrechen
+ return DBUtil.endTransaction(session,false);
+ case JOptionPane.YES_OPTION:
+ // Transaktion durchfuehren
+ return DBUtil.endTransaction(session,true);
+ }
+
+ return true;
+ }
+
+}
Added: trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/event/DatabaseRecordDeletedEvent.java
===================================================================
--- trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/event/DatabaseRecordDeletedEvent.java (rev 0)
+++ trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/event/DatabaseRecordDeletedEvent.java 2013-03-25 21:10:30 UTC (rev 2285)
@@ -0,0 +1,16 @@
+package de.schmitzm.db.hibernate.gui.event;
+
+/**
+ * Event that indicates that a database record was deleted.
+ * @author Martin O.J. Schmitz
+ */
+public class DatabaseRecordDeletedEvent extends DatabaseUpdateEvent {
+ /**
+ * Creates a new event.
+ * @param source object that initiated the database change
+ * @param deletedRecord deleted database entity
+ */
+ public DatabaseRecordDeletedEvent(Object source, Object deletedRecord) {
+ super(source,deletedRecord);
+ }
+}
Added: trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/event/DatabaseRecordUpdatedEvent.java
===================================================================
--- trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/event/DatabaseRecordUpdatedEvent.java (rev 0)
+++ trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/event/DatabaseRecordUpdatedEvent.java 2013-03-25 21:10:30 UTC (rev 2285)
@@ -0,0 +1,17 @@
+package de.schmitzm.db.hibernate.gui.event;
+
+/**
+ * Event that indicates that a database record was changed.
+ * @author Martin O.J. Schmitz
+ */
+public class DatabaseRecordUpdatedEvent extends DatabaseUpdateEvent {
+ /**
+ * Creates a new event.
+ * @param source object that initiated the database change
+ * @param updatedRecord updated database entity
+ */
+ public DatabaseRecordUpdatedEvent(Object source, Object updatedRecord) {
+ super(source,updatedRecord);
+ }
+
+}
Added: trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/event/DatabaseSearchListener.java
===================================================================
--- trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/event/DatabaseSearchListener.java (rev 0)
+++ trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/event/DatabaseSearchListener.java 2013-03-25 21:10:30 UTC (rev 2285)
@@ -0,0 +1,15 @@
+package de.schmitzm.db.hibernate.gui.event;
+
+import java.util.List;
+
+/**
+ * Listener, which reacts on search results of ...
+ * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a>
+ *
+ */
+public interface DatabaseSearchListener<E> {
+ /**
+ * Called by ....
+ */
+ public void performSeachResult(String pattern, List<E> searchResult);
+}
Added: trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/event/DatabaseUpdateAdapter.java
===================================================================
--- trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/event/DatabaseUpdateAdapter.java (rev 0)
+++ trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/event/DatabaseUpdateAdapter.java 2013-03-25 21:10:30 UTC (rev 2285)
@@ -0,0 +1,26 @@
+package de.schmitzm.db.hibernate.gui.event;
+
+/**
+ * Empty implementation of {@link DatabaseUpdateListener}.
+ * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a>
+ *
+ */
+public class DatabaseUpdateAdapter {
+ /**
+ * Called if a table changed.
+ */
+ public void databaseUpdated(DatabaseUpdateEvent e) {
+ }
+
+ /**
+ * Called when database connection was established.
+ */
+ public void databaseConnectionEstablished() {
+ }
+
+ /**
+ * Called when database connection was closed
+ */
+ public void databaseConnectionReleased() {
+ }
+}
Added: trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/event/DatabaseUpdateEmitter.java
===================================================================
--- trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/event/DatabaseUpdateEmitter.java (rev 0)
+++ trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/event/DatabaseUpdateEmitter.java 2013-03-25 21:10:30 UTC (rev 2285)
@@ -0,0 +1,99 @@
+package de.schmitzm.db.hibernate.gui.event;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This class represents a central objects, which informs all connected
+ * {@link DatabaseUpdateListener} about database changes by invoking
+ * {@link #fireDatabaseUpdate(DatabaseUpdateEvent)} method.<br>
+ * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a>
+ *
+ */
+public class DatabaseUpdateEmitter {
+ /** Holds the connected listeners. */
+ protected List<DatabaseUpdateListener> listeners = new ArrayList<DatabaseUpdateListener>();
+
+ /**
+ * Adds a listener. Every {@link DatabaseUpdateListener}
+ * can only be connected once.
+ * @return {@code true} if the listener was added
+ */
+ public boolean addDatabaseUpdateListener(DatabaseUpdateListener l) {
+ if ( listeners.contains(l) )
+ return false;
+ return listeners.add(l);
+ }
+
+ /**
+ * Removes a listener.
+ */
+ public boolean removeDatabaseUpdateListener(DatabaseUpdateListener l) {
+ return listeners.remove(l);
+ }
+
+ /**
+ * Returns all connected listeners.
+ */
+ public List<DatabaseUpdateListener> getDatabaseUpdateListeners() {
+ return listeners;
+ }
+
+ /**
+ * Calls {@link DatabaseUpdateListener#databaseUpdated(DatabaseUpdateEvent)}
+ * for all connected listeners.
+ */
+ public void fireDatabaseUpdate(DatabaseUpdateEvent e) {
+ for (DatabaseUpdateListener l : listeners)
+ l.databaseUpdated(e);
+ }
+
+ /**
+ * Calls {@link DatabaseUpdateListener#databaseUpdated(DatabaseUpdateEvent)}
+ * for all connected listeners.
+ * @param source object which initiates the event
+ * @param updatedRecord updated database entity
+ */
+ public void fireDatabaseUpdate(Object source, Object updatedRecord) {
+ fireDatabaseUpdate(new DatabaseUpdateEvent(source, updatedRecord));
+ }
+
+ /**
+ * Calls {@link DatabaseUpdateListener#databaseUpdated(DatabaseUpdateEvent)}
+ * for all connected listeners.
+ * @param source object which initiates the event
+ * @param deletedRecord deleted database entity
+ */
+ public void fireDatabaseRecordDeleted(Object source, Object deletedRecord) {
+ fireDatabaseUpdate(new DatabaseRecordDeletedEvent(source, deletedRecord));
+ }
+
+ /**
+ * Calls {@link DatabaseUpdateListener#databaseUpdated(DatabaseUpdateEvent)}
+ * for all connected listeners
+ * @param source object which initiates the event
+ * @param updatedType updated type/table
+ */
+ public void fireDatabaseUpdate(Object source, Class<?> updatedType) {
+ fireDatabaseUpdate(new DatabaseUpdateEvent(source, updatedType));
+ }
+
+ /**
+ * Calls {@link DatabaseUpdateListener#databaseConnectionEstablished()}
+ * for all connected listeners.
+ */
+ public void fireDatabaseConnectionEstablished() {
+ for (DatabaseUpdateListener l : listeners)
+ l.databaseConnectionStateChanged(true);
+ }
+
+ /**
+ * Calls {@link DatabaseUpdateListener#databaseConnectionReleased()}
+ * for all connected listeners.
+ */
+ public void fireDatabaseConnectionReleased() {
+ for (DatabaseUpdateListener l : listeners)
+ l.databaseConnectionStateChanged(false);
+ }
+
+}
Added: trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/event/DatabaseUpdateEvent.java
===================================================================
--- trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/event/DatabaseUpdateEvent.java (rev 0)
+++ trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/event/DatabaseUpdateEvent.java 2013-03-25 21:10:30 UTC (rev 2285)
@@ -0,0 +1,126 @@
+package de.schmitzm.db.hibernate.gui.event;
+
+import de.schmitzm.db.hibernate.DBUtil;
+
+/**
+ * Ereignis einer DB-Aenderungen (Daten, Verbindung, ...).
+ * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a>
+ *
+ */
+public class DatabaseUpdateEvent{
+ /** Enthaelt die Tabelle, die sich geaendert hat. */
+ protected String updatedTable = null;
+ /** Enthaelt den zur Tabelle korrespondierenden Datentyp,
+ * der sich geaendert hat. */
+ protected Class<?> updatedType = null;
+ /** Enthaelt den Datensatz, der sich geaendert hat. */
+ protected Object updatedRecord = null;
+
+ /** Enthaelt des Ausloeser des Events. */
+ protected Object updateSource = null;
+
+ /**
+ * Erzeugt ein neues Event. Dem Event wird kein Datensatz zugeordnet.
+ * @param source Ausloeser des Events.
+ * @param updatedTable Tabelle, die sich geaendert hat
+ * @param updatedType Zu der Tabelle korrespondierender Datentyp
+ */
+ public <E> DatabaseUpdateEvent(Object source, String updatedTable, Class<E> updatedType) {
+ this.updateSource = source;
+ this.updatedType = updatedType;
+ this.updatedTable = updatedTable;
+ this.updatedRecord = null;
+ }
+
+ /**
+ * Erzeugt ein neues Event. Dem Event wird kein Datentyp zugeordnet.
+ * @param source Ausloeser des Events.
+ * @param updatedTable Tabelle, die sich geaendert hat
+ * @param updatedRecord Datensatz, der sich geaendert hat
+ */
+ public <E> DatabaseUpdateEvent(Object source, String updatedTable, Object updatedRecord) {
+ this.updateSource = source;
+ this.updatedTable = updatedTable;
+ this.updatedType = updatedRecord != null ? updatedRecord.getClass() : null;
+ this.updatedRecord = updatedRecord;
+ }
+
+ /**
+ * Erzeugt ein allgemeines Event. Dem Event wird weder ein Datentyp,
+ * noch eine Tabelle oder ein Datensatz zugeordnet.
+ */
+ public <E> DatabaseUpdateEvent() {
+ this(null, null,(Class<?>)null);
+ }
+
+ /**
+ * Erzeugt ein allgemeines Event. Dem Event wird weder ein Datentyp,
+ * noch eine Tabelle oder ein Datensatz zugeordnet.
+ * @param source Ausloeser des Events.
+ */
+ public <E> DatabaseUpdateEvent(Object source) {
+ this(source, null,(Class<?>)null);
+ }
+
+ /**
+ * Erzeugt ein neues Event. Dem Event wird weder ein Datentyp,
+ * noch ein Datensatz zugeordnet.
+ * @param source Ausloeser des Events.
+ * @param updatedTable Tabelle, die sich geaendert hat
+ */
+ public <E> DatabaseUpdateEvent(Object source, String updatedTable) {
+ this(source, updatedTable,(Class<?>)null);
+ }
+
+ /**
+ * Erzeugt ein neues Event. Die Tablle wird ueber
+ * {@link DBUtil#getDatabaseTable(Class)} ermittelt. Dem Event
+ * wird kein Datensatz zugeordnet.
+ * @param source Ausloeser des Events.
+ * @param updatedType Datentyp, der sich geaendert hat
+ */
+ public <E> DatabaseUpdateEvent(Object source, Class<E> updatedType) {
+ this(source, DBUtil.getDatabaseTable(updatedType), updatedType);
+ }
+
+ /**
+ * Erzeugt ein neues Event. Die Tablle wird ueber
+ * {@link DBUtil#getDatabaseTable(Class)} ermittelt.
+ * @param source Ausloeser des Events.
+ * @param updatedRecord Datensatz, der sich geaendert hat
+ */
+ public <E> DatabaseUpdateEvent(Object source, Object updatedRecord) {
+ this(source, updatedRecord != null ? DBUtil.getDatabaseTable( updatedRecord.getClass()) : null, updatedRecord);
+ }
+
+ /**
+ * Liefert den Ausloeser des Events.
+ */
+ public Object getSource() {
+ return updateSource;
+ }
+
+ /**
+ * Liefert die Tabelle, die sich geaendert hat.
+ */
+ public String getUpdatedTable() {
+ return updatedTable;
+ }
+
+ /**
+ * Liefert den Datentyp, der geaendert hat.
+ */
+ public Class<?> getUpdatedType() {
+ return updatedType;
+ }
+
+ /**
+ * Liefert den Datensatz, der geaendert hat.
+ */
+ public Object getUpdatedRecord() {
+ return updatedRecord;
+ }
+
+
+
+}
Added: trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/event/DatabaseUpdateListener.java
===================================================================
--- trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/event/DatabaseUpdateListener.java (rev 0)
+++ trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/event/DatabaseUpdateListener.java 2013-03-25 21:10:30 UTC (rev 2285)
@@ -0,0 +1,20 @@
+package de.schmitzm.db.hibernate.gui.event;
+
+/**
+ * Listener, which reacts on database changes.
+ * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a>
+ *
+ */
+public interface DatabaseUpdateListener {
+ /**
+ * Called when a table changes.
+ */
+ public void databaseUpdated(DatabaseUpdateEvent e);
+
+ /**
+ * Called when the database connection state changes.
+ * @param connected indicates whether the connection was established or closed
+ */
+ public void databaseConnectionStateChanged(boolean connected);
+
+}
Modified: trunk/schmitzm-hibernate/src/main/resources/de/schmitzm/db/hibernate/resource/locales/HibernateResourceBundle.properties
===================================================================
--- trunk/schmitzm-hibernate/src/main/resources/de/schmitzm/db/hibernate/resource/locales/HibernateResourceBundle.properties 2013-03-25 21:07:57 UTC (rev 2284)
+++ trunk/schmitzm-hibernate/src/main/resources/de/schmitzm/db/hibernate/resource/locales/HibernateResourceBundle.properties 2013-03-25 21:10:30 UTC (rev 2285)
@@ -35,4 +35,10 @@
HibernateApplication.db.conn.dialog.title=Database connection
HibernateApplication.db.conn.progress.mess=Establishing database connection ...
+GUIUtil.save.confirm.mess=Changes were made. Do you want to save the changes in database?
+GUIUtil.save.confirm.mess.title=Save changes
+DatabaseSearchQueryToolBar.Query=Query:
+DatabaseSearchQueryToolBar.SEARCH=search
+DatabaseSearchQueryToolBar.SEARCH.desc=Submit search query
+
Modified: trunk/schmitzm-hibernate/src/main/resources/de/schmitzm/db/hibernate/resource/locales/HibernateResourceBundle_de.properties
===================================================================
--- trunk/schmitzm-hibernate/src/main/resources/de/schmitzm/db/hibernate/resource/locales/HibernateResourceBundle_de.properties 2013-03-25 21:07:57 UTC (rev 2284)
+++ trunk/schmitzm-hibernate/src/main/resources/de/schmitzm/db/hibernate/resource/locales/HibernateResourceBundle_de.properties 2013-03-25 21:10:30 UTC (rev 2285)
@@ -35,3 +35,9 @@
HibernateApplication.db.conn.dialog.title=Datenbank-Anmeldung
HibernateApplication.db.conn.progress.mess=Datenbank-Verbindung wird aufgebaut...
+GUIUtil.save.confirm.mess=Es wurden Änderungen vorgenommen. Wollen Sie diese speichern?
+GUIUtil.save.confirm.mess.title=Änderungen speichern
+
+DatabaseSearchQueryToolBar.Query=Anfrage:
+DatabaseSearchQueryToolBar.SEARCH=suchen
+DatabaseSearchQueryToolBar.SEARCH.desc=Suchanfrage absetzen
More information about the Schmitzm-commits
mailing list