Java tutorial
/* * EuroCarbDB, a framework for carbohydrate bioinformatics * * Copyright (c) 2006-2009, Eurocarb project, or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU * Lesser General Public License, as published by the Free Software Foundation. * A copy of this license accompanies this distribution in the file LICENSE.txt. * * 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 Lesser General Public License * for more details. * * Last commit: $Rev: 1870 $ by $Author: david@nixbioinf.org $ on $Date:: 2010-02-23 #$ */ package org.eurocarbdb.dataaccess; // stdlib imports import java.util.*; import java.io.File; import java.io.Serializable; import java.net.URI; import java.net.URISyntaxException; // 3rd party imports import org.apache.log4j.Logger; import org.apache.commons.configuration.Configuration; import org.apache.commons.configuration.ConfigurationUtils; import org.apache.commons.configuration.ConfigurationException; import org.apache.commons.configuration.CompositeConfiguration; import org.apache.commons.configuration.PropertiesConfiguration; import org.hibernate.Criteria; import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.criterion.CriteriaSpecification; import org.hibernate.HibernateException; import org.hibernate.criterion.Order; import org.hibernate.criterion.MatchMode; import org.hibernate.criterion.Projections; import org.hibernate.criterion.Restrictions; import org.hibernate.criterion.ProjectionList; // eurocarb imports import org.eurocarbdb.dataaccess.core.*; // import org.eurocarbdb.dataaccess.hibernate.HibernateUtil; import org.eurocarbdb.dataaccess.EntityManager; // static imports import static org.eurocarbdb.util.StringUtils.CR; import static org.eurocarbdb.util.StringUtils.coerce; import static org.eurocarbdb.util.StringUtils.repeat; /* class Eurocarb *//********************************************** *<p> * Core class for exposing key elements of data access and funcionality * for the Eurocarb platform. *</p> *<p> * All access to EurocarbDB and associated data normally occurs through * an {@link EntityManager} instance, which essentially acts as a factory class * for EurocarbDB objects. *</p> *<p> * Code using EntityManagers to create/manipulate data objects * should statically import the getEntityManager methods from * this class at their own convenience. *</p> *<p> * ie: *<tt> * import static org.eurocarbdb.dataaccess.Eurocarb.getEntityManager; *</tt> *</p> *<p> * Access to project-wide constants and settings is provided through * the getProperty method of this class. *</p> * * @author mjh */ public final class Eurocarb { /** Logging handle. */ public static final Logger log = Logger.getLogger(Eurocarb.class); /** This class is not intended to be instantiated. */ private Eurocarb() { } /* * multiple sections to this class: * - EntityManager stuff * - Project-wide configuration properties * - user access & authentication * - utility methods */ //~~~~~~~~~~~~~~~~~ EntityManager stuff ~~~~~~~~~~~~~~~~~~~~~~~ private static final Map<String, EntityManager> Entity_Managers = new HashMap<String, EntityManager>(); /*/************************************************************** * * Register all default EMs here. */ static { registerEntityManager("default", new HibernateEntityManager()); } /** * Looks up a Eurocarb data object using its canonical id. */ public static final <T> T lookup(Class<T> c, int id) { return getEntityManager().lookup(c, id); } /* getEntityManager *//**************************************** * * Returns the default EntityManager. */ public static final EntityManager getEntityManager() { return getEntityManager("default"); } /** * Clone of getEntityManager(), just prevents the need to cast my hand. * @return */ public static final HibernateEntityManager getHibernateEntityManager() { return (HibernateEntityManager) getEntityManager("default"); } public static final Session getHibernateSession() { return getHibernateEntityManager().getHibernateSession(); } public static final Query getHqlQuery(String query) { return getHibernateEntityManager().getHibernateSession().createQuery(query); } /* getEntityManager *//**************************************** * * Returns the EntityManager associated with the given name. * The default EntityManager can be obtained via the String name * "default". */ static final EntityManager getEntityManager(String name) { assert name != null; EntityManager em = Entity_Managers.get(name); assert (em != null); return em; } /* registerEntityManager *//*********************************** * * Registers an EntityManager for use. */ static final void registerEntityManager(String name, EntityManager em) { assert em != null; Entity_Managers.put(name, em); } // mjh: this is a placeholder for functionality that may be added in the future /* static final void unregisterEntityManager( String name ) { assert( Entity_Managers.contains( name ) ); Entity_Managers.remove( name ); } */ //~~~~~~~~~~~~~~~~~ User/Contributor stuff ~~~~~~~~~~~~~~~~~~~~ /** * This is the ID of the {@link Contributor} that is "logged into" the current Thread. * This will be 0 (the guest contributor id) if noone is logged into this Thread. */ static ThreadLocal<Integer> currentContributorId = new ThreadLocal<Integer>(); /** This is the {@link Contributor} that is logged into the current Thread. If noone * is logged in atm, then this will be the "guest" contributor. */ static ThreadLocal<Contributor> currentContributor = new ThreadLocal<Contributor>(); /** * Returns the {@link Contributor} whose contributor_id is bound * to the current thread. */ public static final Contributor getCurrentContributor() { if (currentContributor.get() != null) return currentContributor.get(); Integer contrib_id = currentContributorId.get(); if (contrib_id == null || contrib_id == 0) { Contributor guest = Contributor.getGuestContributor(); assert currentContributor != null; currentContributor.set(guest); } else if (contrib_id < 0) { throw new IllegalArgumentException("currentContributorId was < 0"); } else { Contributor user = getEntityManager().lookup(Contributor.class, contrib_id); if (user == null) { log.warn("Invalid contributorId '" + contrib_id + "'"); return null; } else currentContributor.set(user); } return currentContributor.get(); } //~~~~~~~~~~~~~~~~~~ Config/Property access ~~~~~~~~~~~~~~~~~~~ /** Where to find main property config file. */ public static final String EUROCARB_CONF = "eurocarbdb-core.properties"; /** Hash of project-wide properties. */ static CompositeConfiguration config = null; // init property hash from conf file(s). static void initConfig() { //if ( config == null ) config = new CompositeConfiguration(); try { // log.info("adding configuration: " + EUROCARB_OVERRIDES_CONF ); // config.addConfiguration( // new PropertiesConfiguration( EUROCARB_OVERRIDES_CONF ) ); // log.info( "configured properties for core-api: \n" // + ConfigurationUtils.toString( config ) ); log.info("adding core-api configuration: " + EUROCARB_CONF); config.addConfiguration(new PropertiesConfiguration(EUROCARB_CONF)); } catch (ConfigurationException ex) { throw new RuntimeException(ex); } if (log.isInfoEnabled()) { log.info(CR + repeat('=', 20) + " configured eurocarb core-api properties " + repeat('=', 20) + CR + ConfigurationUtils.toString(config) + CR + repeat('=', 80)); } } /* getConfiguration *//**************************************** * * Returns the current core-api configuration. */ public static final CompositeConfiguration getConfiguration() { if (config == null) initConfig(); return config; } /* getProperty *//********************************************* * * Shortcut method that returns the value of the passed property * name. Throws an exception if the given property name doesn't * exist in the property hash. */ public static final String getProperty(String property_name) { if (!getConfiguration().containsKey(property_name)) { log.warn("Given property '" + property_name + "' does not exist in current config"); return null; } try { return (String) getConfiguration().getProperty(property_name); } catch (Exception e) { log.warn("Caught exception while looking up property '" + property_name + "':", e); return null; } } /* public static final void LogConfig() { StringBuffer sb = new StringBuffer(); sb.append("Configured Eurocarb properties:" + CR ); Iterator allKeys = config.getKeys(); while ( allKeys.hasNext() ) { Object key = allKeys.next(); sb.append( " " + key + " = " + config.getProperty((String) key) + CR ); } log.info( sb.toString() ); } */ /** * Same as {@link #getProperty}, except the property value is pre-cast to * the given {@link Class}. Eg: *<pre> * int limit = getProperty("some_property_name", Integer.class ); *</pre> * This method works fine for the majority of Java primitive types * ({@link Integer}, {@link Long}, {@link Float}, {@link Double}, etc), * with the exception of {@link Character}. * * @throws ClassCastException * If the property value could not be coerced to the given class. * @throws NumberFormatException * If the desired class was a primitive numeric type and couldn't be parsed. */ public static final <T> T getProperty(String property_name, Class<T> as_class) { String property_value = getProperty(property_name); return coerce(property_value, as_class); } /* getPropertyAsURI *//**************************************** * * Convenience method to return the value of a property as a URI object. * @deprecated use <tt>getProperty("property_name", URI.class );</tt> */ @Deprecated public static final URI getPropertyAsURI(String property_name) { String url_property = getProperty(property_name); // basic sanity check if (url_property == null || url_property.length() == 0) throw new RuntimeException("Expected a value for property '" + url_property + "'"); // ensure it's a valid URI URI uri; try { uri = new URI(url_property); } catch (URISyntaxException e) { throw new RuntimeException("Malformed url syntax for property '" + url_property + "'"); } return uri; } //~~~~~~~~~~~~~~~~~~~ UTILITY METHODS ~~~~~~~~~~~~~~~~~~~~~~~~~~~ /* getRecentContributions *//********************************** * * Returns a {@link List} of given length of the most recently * {@link Contributed} objects to the current data store, in order * of most to least recent, or an empty list if there are no * {@link Contributed} objects. Note that this method only * returns additions -- modifications to older objects will not * be included. * * @see Contributor.getMyRecentContributions(int) */ public static List<Contributed> getRecentContributions(int max_results) { // hibernate cannot limit polymorphic queries in the database // we have to do it one class by one log.debug("looking up all Contributed objects"); // get all contributed objects ArrayList<Contributed> changes = new ArrayList<Contributed>(); changes.addAll(getRecentlyContributed(GlycanSequence.class, max_results)); changes.addAll(getRecentlyContributed(Evidence.class, max_results)); /** * FIXME: I do have a fix in mind for this, but I want to make sure I catch * everything that was going via BiologicalContext before I reimplement the * Contributed interface on this class. */ //changes.addAll( getRecentlyContributed( BiologicalContext.class, max_results)); changes.addAll(getRecentlyContributed(Reference.class, max_results)); // sort by date Collections.sort(changes, new Comparator<Contributed>() { public int compare(Contributed o1, Contributed o2) { return -o1.getDateEntered().compareTo(o2.getDateEntered()); } public boolean equals(Object obj) { return this == obj; } }); // get sublist if (changes.size() < max_results) { return changes; } return changes.subList(0, max_results); } public static <T> List<T> getRecentlyContributed(Class<T> c, int max_results) { // does c implement Contributed? if (Contributed.class.isAssignableFrom(c)) { /* TODO: remove explicit hibernate reference */ List results = ((HibernateEntityManager) getEntityManager()).getHibernateSession().createCriteria(c) .setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY) .addOrder(Order.desc("dateEntered")).setMaxResults(max_results).list(); if (results == null) return Collections.emptyList(); return (List<T>) results; } else { List results = ((HibernateEntityManager) getEntityManager()).getHibernateSession().createCriteria(c) .addOrder(Order.desc("id")).setMaxResults(max_results).list(); if (results == null) return Collections.emptyList(); return (List<T>) results; } } } // end class