Browse Source
Merge in CORE/base-third from ~BRYANT/base-third:research/11.0 to research/11.0 * commit 'b76d16056e9cb418e16ec3295a65c85e14dff28d': REPORT-120996 合并third REPORT-113277 Hibernate组件修复CVE漏洞 REPORT-108658 预览与导出pdf字体颜色不一致 【问题原因】字体填充颜色其实是一样的,但导出pdf后,字体存在黑色描边。 导出pdf时,若字体为粗体,会对字体进行描边。描边的颜色会使用到realPaint的颜色。在创建Graphics的时候,没有对realPaint进行初始化,正常情况下,是使用setPaint对其进行赋值。若此后再进行绘制,且没有调用setPaint方法,realPaint则为null,当字体为粗体时,会使用之前的颜色对其进行描边,字体颜色看起来会显示异常。 【改动思路】创建时,使用当前的realPaint进行初始化。 REPORT-109844 v8 linux arm 从11.4退回10.9 REPORT-109123 fine-third-11.0.jar中含有.bak文件待清理 REPORT-108344 用户密码被记录进日志,手机号邮箱被明文记录research/11.0
Bryant-赵东升
6 months ago
22 changed files with 4765 additions and 771 deletions
@ -0,0 +1,13 @@
|
||||
# fine-hibernate |
||||
|
||||
改包名的hibernate(5.1.0.Final),包括: |
||||
|
||||
- hibernate-commons-annotations |
||||
- hibernate-core |
||||
- hibernate-entitymanager |
||||
- hibernate-java8 |
||||
- hibernate-jpamodelgen |
||||
|
||||
|
||||
定制: |
||||
REPORT-108344: debug日志级别,hibernate会打印出entity信息,没找到控制项,屏蔽一下相关代码 |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,390 @@
|
||||
/* |
||||
* Hibernate, Relational Persistence for Idiomatic Java |
||||
* |
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later. |
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/ |
||||
package com.fr.third.org.hibernate.event.internal; |
||||
|
||||
import java.io.Serializable; |
||||
import java.util.Map; |
||||
|
||||
import com.fr.third.org.hibernate.HibernateException; |
||||
import com.fr.third.org.hibernate.action.internal.CollectionRecreateAction; |
||||
import com.fr.third.org.hibernate.action.internal.CollectionRemoveAction; |
||||
import com.fr.third.org.hibernate.action.internal.CollectionUpdateAction; |
||||
import com.fr.third.org.hibernate.action.internal.QueuedOperationCollectionAction; |
||||
import com.fr.third.org.hibernate.collection.spi.PersistentCollection; |
||||
import com.fr.third.org.hibernate.engine.internal.Cascade; |
||||
import com.fr.third.org.hibernate.engine.internal.CascadePoint; |
||||
import com.fr.third.org.hibernate.engine.internal.Collections; |
||||
import com.fr.third.org.hibernate.engine.spi.ActionQueue; |
||||
import com.fr.third.org.hibernate.engine.spi.CascadingAction; |
||||
import com.fr.third.org.hibernate.engine.spi.CascadingActions; |
||||
import com.fr.third.org.hibernate.engine.spi.CollectionEntry; |
||||
import com.fr.third.org.hibernate.engine.spi.CollectionKey; |
||||
import com.fr.third.org.hibernate.engine.spi.EntityEntry; |
||||
import com.fr.third.org.hibernate.engine.spi.PersistenceContext; |
||||
import com.fr.third.org.hibernate.engine.spi.SessionImplementor; |
||||
import com.fr.third.org.hibernate.engine.spi.Status; |
||||
import com.fr.third.org.hibernate.event.service.spi.EventListenerRegistry; |
||||
import com.fr.third.org.hibernate.event.spi.EventSource; |
||||
import com.fr.third.org.hibernate.event.spi.EventType; |
||||
import com.fr.third.org.hibernate.event.spi.FlushEntityEvent; |
||||
import com.fr.third.org.hibernate.event.spi.FlushEntityEventListener; |
||||
import com.fr.third.org.hibernate.event.spi.FlushEvent; |
||||
import com.fr.third.org.hibernate.internal.CoreMessageLogger; |
||||
import com.fr.third.org.hibernate.internal.util.EntityPrinter; |
||||
import com.fr.third.org.hibernate.internal.util.collections.IdentityMap; |
||||
import com.fr.third.org.hibernate.internal.util.collections.LazyIterator; |
||||
import com.fr.third.org.hibernate.persister.entity.EntityPersister; |
||||
|
||||
import com.fr.third.org.jboss.logging.Logger; |
||||
|
||||
/** |
||||
* A convenience base class for listeners whose functionality results in flushing. |
||||
* |
||||
* @author Steve Ebersole |
||||
*/ |
||||
public abstract class AbstractFlushingEventListener implements Serializable { |
||||
|
||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger( CoreMessageLogger.class, AbstractFlushingEventListener.class.getName() ); |
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Pre-flushing section
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
/** |
||||
* Coordinates the processing necessary to get things ready for executions |
||||
* as db calls by preping the session caches and moving the appropriate |
||||
* entities and collections to their respective execution queues. |
||||
* |
||||
* @param event The flush event. |
||||
* @throws HibernateException Error flushing caches to execution queues. |
||||
*/ |
||||
protected void flushEverythingToExecutions(FlushEvent event) throws HibernateException { |
||||
|
||||
LOG.trace( "Flushing session" ); |
||||
|
||||
EventSource session = event.getSession(); |
||||
|
||||
final PersistenceContext persistenceContext = session.getPersistenceContext(); |
||||
session.getInterceptor().preFlush( new LazyIterator( persistenceContext.getEntitiesByKey() ) ); |
||||
|
||||
prepareEntityFlushes( session, persistenceContext ); |
||||
// we could move this inside if we wanted to
|
||||
// tolerate collection initializations during
|
||||
// collection dirty checking:
|
||||
prepareCollectionFlushes( persistenceContext ); |
||||
// now, any collections that are initialized
|
||||
// inside this block do not get updated - they
|
||||
// are ignored until the next flush
|
||||
|
||||
persistenceContext.setFlushing( true ); |
||||
try { |
||||
int entityCount = flushEntities( event, persistenceContext ); |
||||
int collectionCount = flushCollections( session, persistenceContext ); |
||||
|
||||
event.setNumberOfEntitiesProcessed( entityCount ); |
||||
event.setNumberOfCollectionsProcessed( collectionCount ); |
||||
} |
||||
finally { |
||||
persistenceContext.setFlushing(false); |
||||
} |
||||
|
||||
//some statistics
|
||||
logFlushResults( event ); |
||||
} |
||||
|
||||
@SuppressWarnings( value = {"unchecked"} ) |
||||
private void logFlushResults(FlushEvent event) { |
||||
if ( !LOG.isDebugEnabled() ) { |
||||
return; |
||||
} |
||||
final EventSource session = event.getSession(); |
||||
final PersistenceContext persistenceContext = session.getPersistenceContext(); |
||||
LOG.debugf( |
||||
"Flushed: %s insertions, %s updates, %s deletions to %s objects", |
||||
session.getActionQueue().numberOfInsertions(), |
||||
session.getActionQueue().numberOfUpdates(), |
||||
session.getActionQueue().numberOfDeletions(), |
||||
persistenceContext.getNumberOfManagedEntities() |
||||
); |
||||
LOG.debugf( |
||||
"Flushed: %s (re)creations, %s updates, %s removals to %s collections", |
||||
session.getActionQueue().numberOfCollectionCreations(), |
||||
session.getActionQueue().numberOfCollectionUpdates(), |
||||
session.getActionQueue().numberOfCollectionRemovals(), |
||||
persistenceContext.getCollectionEntries().size() |
||||
); |
||||
//new EntityPrinter( session.getFactory() ).toString(persistenceContext.getEntitiesByKey().entrySet());
|
||||
} |
||||
|
||||
/** |
||||
* process cascade save/update at the start of a flush to discover |
||||
* any newly referenced entity that must be passed to saveOrUpdate(), |
||||
* and also apply orphan delete |
||||
*/ |
||||
private void prepareEntityFlushes(EventSource session, PersistenceContext persistenceContext) throws HibernateException { |
||||
|
||||
LOG.debug( "Processing flush-time cascades" ); |
||||
|
||||
final Object anything = getAnything(); |
||||
//safe from concurrent modification because of how concurrentEntries() is implemented on IdentityMap
|
||||
for ( Map.Entry<Object,EntityEntry> me : persistenceContext.reentrantSafeEntityEntries() ) { |
||||
// for ( Map.Entry me : IdentityMap.concurrentEntries( persistenceContext.getEntityEntries() ) ) {
|
||||
EntityEntry entry = (EntityEntry) me.getValue(); |
||||
Status status = entry.getStatus(); |
||||
if ( status == Status.MANAGED || status == Status.SAVING || status == Status.READ_ONLY ) { |
||||
cascadeOnFlush( session, entry.getPersister(), me.getKey(), anything ); |
||||
} |
||||
} |
||||
} |
||||
|
||||
private void cascadeOnFlush(EventSource session, EntityPersister persister, Object object, Object anything) |
||||
throws HibernateException { |
||||
session.getPersistenceContext().incrementCascadeLevel(); |
||||
try { |
||||
Cascade.cascade( getCascadingAction(), CascadePoint.BEFORE_FLUSH, session, persister, object, anything ); |
||||
} |
||||
finally { |
||||
session.getPersistenceContext().decrementCascadeLevel(); |
||||
} |
||||
} |
||||
|
||||
protected Object getAnything() { |
||||
return null; |
||||
} |
||||
|
||||
protected CascadingAction getCascadingAction() { |
||||
return CascadingActions.SAVE_UPDATE; |
||||
} |
||||
|
||||
/** |
||||
* Initialize the flags of the CollectionEntry, including the |
||||
* dirty check. |
||||
*/ |
||||
private void prepareCollectionFlushes(PersistenceContext persistenceContext) throws HibernateException { |
||||
|
||||
// Initialize dirty flags for arrays + collections with composite elements
|
||||
// and reset reached, doupdate, etc.
|
||||
|
||||
LOG.debug( "Dirty checking collections" ); |
||||
|
||||
for ( Map.Entry<PersistentCollection,CollectionEntry> entry : |
||||
IdentityMap.concurrentEntries( (Map<PersistentCollection,CollectionEntry>) persistenceContext.getCollectionEntries() )) { |
||||
entry.getValue().preFlush( entry.getKey() ); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 1. detect any dirty entities |
||||
* 2. schedule any entity updates |
||||
* 3. search out any reachable collections |
||||
*/ |
||||
private int flushEntities(final FlushEvent event, final PersistenceContext persistenceContext) throws HibernateException { |
||||
|
||||
LOG.trace( "Flushing entities and processing referenced collections" ); |
||||
|
||||
final EventSource source = event.getSession(); |
||||
final Iterable<FlushEntityEventListener> flushListeners = source.getFactory().getServiceRegistry() |
||||
.getService( EventListenerRegistry.class ) |
||||
.getEventListenerGroup( EventType.FLUSH_ENTITY ) |
||||
.listeners(); |
||||
|
||||
// Among other things, updateReachables() will recursively load all
|
||||
// collections that are moving roles. This might cause entities to
|
||||
// be loaded.
|
||||
|
||||
// So this needs to be safe from concurrent modification problems.
|
||||
|
||||
final Map.Entry<Object,EntityEntry>[] entityEntries = persistenceContext.reentrantSafeEntityEntries(); |
||||
final int count = entityEntries.length; |
||||
|
||||
for ( Map.Entry<Object,EntityEntry> me : entityEntries ) { |
||||
|
||||
// Update the status of the object and if necessary, schedule an update
|
||||
|
||||
EntityEntry entry = me.getValue(); |
||||
Status status = entry.getStatus(); |
||||
|
||||
if ( status != Status.LOADING && status != Status.GONE ) { |
||||
final FlushEntityEvent entityEvent = new FlushEntityEvent( source, me.getKey(), entry ); |
||||
for ( FlushEntityEventListener listener : flushListeners ) { |
||||
listener.onFlushEntity( entityEvent ); |
||||
} |
||||
} |
||||
} |
||||
|
||||
source.getActionQueue().sortActions(); |
||||
|
||||
return count; |
||||
} |
||||
|
||||
/** |
||||
* process any unreferenced collections and then inspect all known collections, |
||||
* scheduling creates/removes/updates |
||||
*/ |
||||
@SuppressWarnings("unchecked") |
||||
private int flushCollections(final EventSource session, final PersistenceContext persistenceContext) throws HibernateException { |
||||
LOG.trace( "Processing unreferenced collections" ); |
||||
|
||||
final Map.Entry<PersistentCollection,CollectionEntry>[] entries = IdentityMap.concurrentEntries( |
||||
(Map<PersistentCollection,CollectionEntry>) persistenceContext.getCollectionEntries() |
||||
); |
||||
|
||||
final int count = entries.length; |
||||
|
||||
for ( Map.Entry<PersistentCollection,CollectionEntry> me : entries ) { |
||||
CollectionEntry ce = me.getValue(); |
||||
if ( !ce.isReached() && !ce.isIgnore() ) { |
||||
Collections.processUnreachableCollection( me.getKey(), session ); |
||||
} |
||||
} |
||||
|
||||
// Schedule updates to collections:
|
||||
|
||||
LOG.trace( "Scheduling collection removes/(re)creates/updates" ); |
||||
|
||||
ActionQueue actionQueue = session.getActionQueue(); |
||||
for ( Map.Entry<PersistentCollection,CollectionEntry> me : |
||||
IdentityMap.concurrentEntries( (Map<PersistentCollection,CollectionEntry>) persistenceContext.getCollectionEntries() )) { |
||||
PersistentCollection coll = me.getKey(); |
||||
CollectionEntry ce = me.getValue(); |
||||
|
||||
if ( ce.isDorecreate() ) { |
||||
session.getInterceptor().onCollectionRecreate( coll, ce.getCurrentKey() ); |
||||
actionQueue.addAction( |
||||
new CollectionRecreateAction( |
||||
coll, |
||||
ce.getCurrentPersister(), |
||||
ce.getCurrentKey(), |
||||
session |
||||
) |
||||
); |
||||
} |
||||
if ( ce.isDoremove() ) { |
||||
session.getInterceptor().onCollectionRemove( coll, ce.getLoadedKey() ); |
||||
actionQueue.addAction( |
||||
new CollectionRemoveAction( |
||||
coll, |
||||
ce.getLoadedPersister(), |
||||
ce.getLoadedKey(), |
||||
ce.isSnapshotEmpty(coll), |
||||
session |
||||
) |
||||
); |
||||
} |
||||
if ( ce.isDoupdate() ) { |
||||
session.getInterceptor().onCollectionUpdate( coll, ce.getLoadedKey() ); |
||||
actionQueue.addAction( |
||||
new CollectionUpdateAction( |
||||
coll, |
||||
ce.getLoadedPersister(), |
||||
ce.getLoadedKey(), |
||||
ce.isSnapshotEmpty(coll), |
||||
session |
||||
) |
||||
); |
||||
} |
||||
|
||||
// todo : I'm not sure the !wasInitialized part should really be part of this check
|
||||
if ( !coll.wasInitialized() && coll.hasQueuedOperations() ) { |
||||
actionQueue.addAction( |
||||
new QueuedOperationCollectionAction( |
||||
coll, |
||||
ce.getLoadedPersister(), |
||||
ce.getLoadedKey(), |
||||
session |
||||
) |
||||
); |
||||
} |
||||
|
||||
} |
||||
|
||||
actionQueue.sortCollectionActions(); |
||||
|
||||
return count; |
||||
} |
||||
|
||||
/** |
||||
* Execute all SQL (and second-level cache updates) in a special order so that foreign-key constraints cannot |
||||
* be violated: <ol> |
||||
* <li> Inserts, in the order they were performed |
||||
* <li> Updates |
||||
* <li> Deletion of collection elements |
||||
* <li> Insertion of collection elements |
||||
* <li> Deletes, in the order they were performed |
||||
* </ol> |
||||
* |
||||
* @param session The session being flushed |
||||
*/ |
||||
protected void performExecutions(EventSource session) { |
||||
LOG.trace( "Executing flush" ); |
||||
|
||||
// IMPL NOTE : here we alter the flushing flag of the persistence context to allow
|
||||
// during-flush callbacks more leniency in regards to initializing proxies and
|
||||
// lazy collections during their processing.
|
||||
// For more information, see HHH-2763
|
||||
try { |
||||
session.getJdbcCoordinator().flushBeginning(); |
||||
session.getPersistenceContext().setFlushing( true ); |
||||
// we need to lock the collection caches before executing entity inserts/updates in order to
|
||||
// account for bi-directional associations
|
||||
session.getActionQueue().prepareActions(); |
||||
session.getActionQueue().executeActions(); |
||||
} |
||||
finally { |
||||
session.getPersistenceContext().setFlushing( false ); |
||||
session.getJdbcCoordinator().flushEnding(); |
||||
} |
||||
} |
||||
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Post-flushing section
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
/** |
||||
* 1. Recreate the collection key -> collection map |
||||
* 2. rebuild the collection entries |
||||
* 3. call Interceptor.postFlush() |
||||
*/ |
||||
protected void postFlush(SessionImplementor session) throws HibernateException { |
||||
|
||||
LOG.trace( "Post flush" ); |
||||
|
||||
final PersistenceContext persistenceContext = session.getPersistenceContext(); |
||||
persistenceContext.getCollectionsByKey().clear(); |
||||
|
||||
// the database has changed now, so the subselect results need to be invalidated
|
||||
// the batch fetching queues should also be cleared - especially the collection batch fetching one
|
||||
persistenceContext.getBatchFetchQueue().clear(); |
||||
|
||||
for ( Map.Entry<PersistentCollection, CollectionEntry> me : IdentityMap.concurrentEntries( persistenceContext.getCollectionEntries() ) ) { |
||||
CollectionEntry collectionEntry = me.getValue(); |
||||
PersistentCollection persistentCollection = me.getKey(); |
||||
collectionEntry.postFlush(persistentCollection); |
||||
if ( collectionEntry.getLoadedPersister() == null ) { |
||||
//if the collection is dereferenced, unset its session reference and remove from the session cache
|
||||
//iter.remove(); //does not work, since the entrySet is not backed by the set
|
||||
persistentCollection.unsetSession( session ); |
||||
persistenceContext.getCollectionEntries() |
||||
.remove(persistentCollection); |
||||
} |
||||
else { |
||||
//otherwise recreate the mapping between the collection and its key
|
||||
CollectionKey collectionKey = new CollectionKey( |
||||
collectionEntry.getLoadedPersister(), |
||||
collectionEntry.getLoadedKey() |
||||
); |
||||
persistenceContext.getCollectionsByKey().put(collectionKey, persistentCollection); |
||||
} |
||||
} |
||||
|
||||
} |
||||
|
||||
protected void postPostFlush(SessionImplementor session) { |
||||
session.getInterceptor().postFlush( new LazyIterator( session.getPersistenceContext().getEntitiesByKey() ) ); |
||||
} |
||||
} |
@ -0,0 +1,104 @@
|
||||
/* |
||||
* Hibernate, Relational Persistence for Idiomatic Java |
||||
* |
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later. |
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/ |
||||
package com.fr.third.org.hibernate.jpa.criteria.expression; |
||||
|
||||
import java.io.Serializable; |
||||
|
||||
import com.fr.third.org.hibernate.jpa.criteria.CriteriaBuilderImpl; |
||||
import com.fr.third.org.hibernate.jpa.criteria.ParameterRegistry; |
||||
import com.fr.third.org.hibernate.jpa.criteria.ValueHandlerFactory; |
||||
import com.fr.third.org.hibernate.jpa.criteria.compile.RenderingContext; |
||||
|
||||
/** |
||||
* Represents a literal expression. |
||||
* |
||||
* @author Steve Ebersole |
||||
*/ |
||||
public class LiteralExpression<T> extends ExpressionImpl<T> implements Serializable { |
||||
private Object literal; |
||||
|
||||
@SuppressWarnings({ "unchecked" }) |
||||
public LiteralExpression(CriteriaBuilderImpl criteriaBuilder, T literal) { |
||||
this( criteriaBuilder, (Class<T>) determineClass( literal ), literal ); |
||||
} |
||||
|
||||
private static Class determineClass(Object literal) { |
||||
return literal == null ? null : literal.getClass(); |
||||
} |
||||
|
||||
public LiteralExpression(CriteriaBuilderImpl criteriaBuilder, Class<T> type, T literal) { |
||||
super( criteriaBuilder, type ); |
||||
this.literal = literal; |
||||
} |
||||
|
||||
@SuppressWarnings({ "unchecked" }) |
||||
public T getLiteral() { |
||||
return (T) literal; |
||||
} |
||||
|
||||
public void registerParameters(ParameterRegistry registry) { |
||||
// nothing to do
|
||||
} |
||||
|
||||
@SuppressWarnings({ "unchecked" }) |
||||
public String render(RenderingContext renderingContext) { |
||||
if ( ValueHandlerFactory.isNumeric( literal ) ) { |
||||
return ValueHandlerFactory.determineAppropriateHandler( (Class) literal.getClass() ).render( literal ); |
||||
} |
||||
else if ( ValueHandlerFactory.isBoolean( literal ) ) { |
||||
return ValueHandlerFactory.determineAppropriateHandler( (Class) literal.getClass() ).render( literal ); |
||||
} |
||||
|
||||
// else...
|
||||
final String parameterName = renderingContext.registerLiteralParameterBinding( getLiteral(), getJavaType() ); |
||||
return ':' + parameterName; |
||||
} |
||||
|
||||
/** |
||||
* Inline String literal. |
||||
* |
||||
* @return escaped String |
||||
*/ |
||||
private String inlineLiteral(String literal) { |
||||
return String.format("\'%s\'", escapeLiteral(literal)); |
||||
} |
||||
|
||||
/** |
||||
* Escape String literal. |
||||
* |
||||
* @return escaped String |
||||
*/ |
||||
private String escapeLiteral(String literal) { |
||||
return literal.replace("'", "''"); |
||||
} |
||||
|
||||
@SuppressWarnings({"unchecked"}) |
||||
public String renderProjection(RenderingContext renderingContext) { |
||||
if (ValueHandlerFactory.isCharacter(literal)) { |
||||
// In case literal is a Character, pass literal.toString() as the argument.
|
||||
return inlineLiteral(literal.toString()); |
||||
} |
||||
// some drivers/servers do not like parameters in the select clause
|
||||
final ValueHandlerFactory.ValueHandler handler = |
||||
ValueHandlerFactory.determineAppropriateHandler(literal.getClass()); |
||||
return handler.render(literal); |
||||
} |
||||
@Override |
||||
@SuppressWarnings({ "unchecked" }) |
||||
protected void resetJavaType(Class targetType) { |
||||
super.resetJavaType( targetType ); |
||||
ValueHandlerFactory.ValueHandler valueHandler = getValueHandler(); |
||||
if ( valueHandler == null ) { |
||||
valueHandler = ValueHandlerFactory.determineAppropriateHandler( targetType ); |
||||
forceConversion( valueHandler ); |
||||
} |
||||
|
||||
if ( valueHandler != null ) { |
||||
literal = valueHandler.convert( literal ); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,235 @@
|
||||
/* |
||||
* Hibernate, Relational Persistence for Idiomatic Java |
||||
* |
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later. |
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/ |
||||
package com.fr.third.org.hibernate.loader.plan.exec.query.internal; |
||||
|
||||
import com.fr.third.org.hibernate.LockMode; |
||||
import com.fr.third.org.hibernate.LockOptions; |
||||
import com.fr.third.org.hibernate.dialect.Dialect; |
||||
import com.fr.third.org.hibernate.internal.util.StringHelper; |
||||
|
||||
/** |
||||
* Largely a copy of the {@link com.fr.third.org.hibernate.sql.Select} class, but changed up slightly to better meet needs |
||||
* of building a SQL SELECT statement from a LoadPlan |
||||
* |
||||
* @author Steve Ebersole |
||||
* @author Gavin King |
||||
*/ |
||||
public class SelectStatementBuilder { |
||||
public final Dialect dialect; |
||||
|
||||
private StringBuilder selectClause = new StringBuilder(); |
||||
private StringBuilder fromClause = new StringBuilder(); |
||||
// private StringBuilder outerJoinsAfterFrom;
|
||||
private String outerJoinsAfterFrom; |
||||
private StringBuilder whereClause; |
||||
// private StringBuilder outerJoinsAfterWhere;
|
||||
private String outerJoinsAfterWhere; |
||||
private StringBuilder orderByClause; |
||||
private String comment; |
||||
private LockOptions lockOptions = new LockOptions(); |
||||
|
||||
private int guesstimatedBufferSize = 20; |
||||
|
||||
/** |
||||
* Constructs a select statement builder object. |
||||
* |
||||
* @param dialect The dialect. |
||||
*/ |
||||
public SelectStatementBuilder(Dialect dialect) { |
||||
this.dialect = dialect; |
||||
} |
||||
|
||||
/** |
||||
* Appends a select clause fragment |
||||
* |
||||
* @param selection The selection fragment |
||||
*/ |
||||
public void appendSelectClauseFragment(String selection) { |
||||
if ( this.selectClause.length() > 0 ) { |
||||
this.selectClause.append( ", " ); |
||||
this.guesstimatedBufferSize += 2; |
||||
} |
||||
this.selectClause.append( selection ); |
||||
this.guesstimatedBufferSize += selection.length(); |
||||
} |
||||
|
||||
/** |
||||
* Appends the from clause fragment. |
||||
* |
||||
* @param fragment The from cause fragment. |
||||
*/ |
||||
public void appendFromClauseFragment(String fragment) { |
||||
if ( this.fromClause.length() > 0 ) { |
||||
this.fromClause.append( ", " ); |
||||
this.guesstimatedBufferSize += 2; |
||||
} |
||||
this.fromClause.append( fragment ); |
||||
this.guesstimatedBufferSize += fragment.length(); |
||||
} |
||||
|
||||
/** |
||||
* Appends the specified table name and alias as a from clause fragment. |
||||
* |
||||
* @param tableName The table name. |
||||
* @param alias The table alias. |
||||
*/ |
||||
public void appendFromClauseFragment(String tableName, String alias) { |
||||
appendFromClauseFragment( tableName + ' ' + alias ); |
||||
} |
||||
|
||||
/** |
||||
* Appends the specified restrictions after "cleaning" the specified value |
||||
* (by trimming and removing 'and ' from beginning and ' and' from the end). |
||||
* If the where clause already exists, this method ensure that ' and ' |
||||
* prefixes the cleaned restrictions. |
||||
* |
||||
* @param restrictions The restrictions. |
||||
*/ |
||||
public void appendRestrictions(String restrictions) { |
||||
final String cleaned = cleanRestrictions( restrictions ); |
||||
if ( StringHelper.isEmpty( cleaned ) ) { |
||||
return; |
||||
} |
||||
|
||||
this.guesstimatedBufferSize += cleaned.length(); |
||||
|
||||
if ( whereClause == null ) { |
||||
whereClause = new StringBuilder( cleaned ); |
||||
} |
||||
else { |
||||
whereClause.append( " and " ).append( cleaned ); |
||||
this.guesstimatedBufferSize += 5; |
||||
} |
||||
} |
||||
|
||||
private String cleanRestrictions(String restrictions) { |
||||
restrictions = restrictions.trim(); |
||||
if ( restrictions.startsWith( "and " ) ) { |
||||
restrictions = restrictions.substring( 4 ); |
||||
} |
||||
if ( restrictions.endsWith( " and" ) ) { |
||||
restrictions = restrictions.substring( 0, restrictions.length()-4 ); |
||||
} |
||||
|
||||
return restrictions; |
||||
} |
||||
|
||||
/** |
||||
* Sets the outer join fragments to be added to the "from" and "where" clauses. |
||||
* |
||||
* @param outerJoinsAfterFrom The outer join fragment to be appended to the "from" clause. |
||||
* @param outerJoinsAfterWhere The outer join fragment to be appended to the "where" clause. |
||||
*/ |
||||
public void setOuterJoins(String outerJoinsAfterFrom, String outerJoinsAfterWhere) { |
||||
this.outerJoinsAfterFrom = outerJoinsAfterFrom; |
||||
|
||||
final String cleanRestrictions = cleanRestrictions( outerJoinsAfterWhere ); |
||||
this.outerJoinsAfterWhere = cleanRestrictions; |
||||
|
||||
this.guesstimatedBufferSize += outerJoinsAfterFrom.length() + cleanRestrictions.length(); |
||||
} |
||||
|
||||
/** |
||||
* Appends the "order by" fragment, prefixed by a comma if the "order by" fragment already |
||||
* exists. |
||||
* |
||||
* @param ordering The "order by" fragment to append. |
||||
*/ |
||||
public void appendOrderByFragment(String ordering) { |
||||
if ( this.orderByClause == null ) { |
||||
this.orderByClause = new StringBuilder(); |
||||
} |
||||
else { |
||||
this.orderByClause.append( ", " ); |
||||
this.guesstimatedBufferSize += 2; |
||||
} |
||||
this.orderByClause.append( ordering ); |
||||
} |
||||
|
||||
/** |
||||
* Sets the comment for the select statement. |
||||
* |
||||
* @param comment The comment. |
||||
*/ |
||||
public void setComment(String comment) { |
||||
this.comment = comment; |
||||
this.guesstimatedBufferSize += comment.length(); |
||||
} |
||||
|
||||
/** |
||||
* Sets the lock mode for the select statement. |
||||
* |
||||
* @param lockMode The lock mode. |
||||
*/ |
||||
public void setLockMode(LockMode lockMode) { |
||||
this.lockOptions.setLockMode( lockMode ); |
||||
} |
||||
|
||||
/** |
||||
* Sets the lock options for the select statement. |
||||
* |
||||
* @param lockOptions The lock options. |
||||
*/ |
||||
public void setLockOptions(LockOptions lockOptions) { |
||||
LockOptions.copy( lockOptions, this.lockOptions ); |
||||
} |
||||
|
||||
/** |
||||
* Construct an SQL <tt>SELECT</tt> statement from the given clauses. |
||||
* |
||||
* @return the SQL <tt>SELECT</tt> statement. |
||||
*/ |
||||
public String toStatementString() { |
||||
StringBuilder buf = new StringBuilder( guesstimatedBufferSize ); |
||||
|
||||
if ( StringHelper.isNotEmpty( comment ) ) { |
||||
buf.append( "/* " ).append( Dialect.escapeComment(comment) ).append( " */ " ); |
||||
} |
||||
|
||||
buf.append( "select " ) |
||||
.append( selectClause ) |
||||
.append( " from " ) |
||||
.append( fromClause ); |
||||
|
||||
if ( StringHelper.isNotEmpty( outerJoinsAfterFrom ) ) { |
||||
buf.append( outerJoinsAfterFrom ); |
||||
} |
||||
|
||||
if ( isNotEmpty( whereClause ) || isNotEmpty( outerJoinsAfterWhere ) ) { |
||||
buf.append( " where " ); |
||||
// the outerJoinsAfterWhere needs to come before where clause to properly
|
||||
// handle dynamic filters
|
||||
if ( StringHelper.isNotEmpty( outerJoinsAfterWhere ) ) { |
||||
buf.append( outerJoinsAfterWhere ); |
||||
if ( isNotEmpty( whereClause ) ) { |
||||
buf.append( " and " ); |
||||
} |
||||
} |
||||
if ( isNotEmpty( whereClause ) ) { |
||||
buf.append( whereClause ); |
||||
} |
||||
} |
||||
|
||||
if ( orderByClause != null ) { |
||||
buf.append( " order by " ).append( orderByClause ); |
||||
} |
||||
|
||||
if ( lockOptions.getLockMode() != LockMode.NONE ) { |
||||
buf = new StringBuilder(dialect.applyLocksToSql( buf.toString(), lockOptions, null ) ); |
||||
} |
||||
|
||||
return dialect.transformSelectString( buf.toString() ); |
||||
} |
||||
|
||||
private boolean isNotEmpty(String string) { |
||||
return StringHelper.isNotEmpty( string ); |
||||
} |
||||
|
||||
private boolean isNotEmpty(StringBuilder builder) { |
||||
return builder != null && builder.length() > 0; |
||||
} |
||||
} |
@ -0,0 +1,127 @@
|
||||
/* |
||||
* Hibernate, Relational Persistence for Idiomatic Java |
||||
* |
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later. |
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/ |
||||
package com.fr.third.org.hibernate.sql; |
||||
import com.fr.third.org.hibernate.dialect.Dialect; |
||||
|
||||
import java.util.Iterator; |
||||
import java.util.LinkedHashMap; |
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* An SQL <tt>DELETE</tt> statement |
||||
* |
||||
* @author Gavin King |
||||
*/ |
||||
public class Delete { |
||||
|
||||
private String tableName; |
||||
private String versionColumnName; |
||||
private String where; |
||||
|
||||
private Map primaryKeyColumns = new LinkedHashMap(); |
||||
|
||||
private String comment; |
||||
public Delete setComment(String comment) { |
||||
this.comment = comment; |
||||
return this; |
||||
} |
||||
|
||||
public Delete setTableName(String tableName) { |
||||
this.tableName = tableName; |
||||
return this; |
||||
} |
||||
|
||||
public String toStatementString() { |
||||
StringBuilder buf = new StringBuilder( tableName.length() + 10 ); |
||||
if ( comment!=null ) { |
||||
buf.append( "/* " ).append(Dialect.escapeComment(comment)).append( " */ " ); |
||||
} |
||||
buf.append( "delete from " ).append(tableName); |
||||
if ( where != null || !primaryKeyColumns.isEmpty() || versionColumnName != null ) { |
||||
buf.append( " where " ); |
||||
} |
||||
boolean conditionsAppended = false; |
||||
Iterator iter = primaryKeyColumns.entrySet().iterator(); |
||||
while ( iter.hasNext() ) { |
||||
Map.Entry e = (Map.Entry) iter.next(); |
||||
buf.append( e.getKey() ).append( '=' ).append( e.getValue() ); |
||||
if ( iter.hasNext() ) { |
||||
buf.append( " and " ); |
||||
} |
||||
conditionsAppended = true; |
||||
} |
||||
if ( where!=null ) { |
||||
if ( conditionsAppended ) { |
||||
buf.append( " and " ); |
||||
} |
||||
buf.append( where ); |
||||
conditionsAppended = true; |
||||
} |
||||
if ( versionColumnName!=null ) { |
||||
if ( conditionsAppended ) { |
||||
buf.append( " and " ); |
||||
} |
||||
buf.append( versionColumnName ).append( "=?" ); |
||||
} |
||||
return buf.toString(); |
||||
} |
||||
|
||||
public Delete setWhere(String where) { |
||||
this.where=where; |
||||
return this; |
||||
} |
||||
|
||||
public Delete addWhereFragment(String fragment) { |
||||
if ( where == null ) { |
||||
where = fragment; |
||||
} |
||||
else { |
||||
where += ( " and " + fragment ); |
||||
} |
||||
return this; |
||||
} |
||||
|
||||
public Delete setPrimaryKeyColumnNames(String[] columnNames) { |
||||
this.primaryKeyColumns.clear(); |
||||
addPrimaryKeyColumns(columnNames); |
||||
return this; |
||||
} |
||||
|
||||
public Delete addPrimaryKeyColumns(String[] columnNames) { |
||||
for ( String columnName : columnNames ) { |
||||
addPrimaryKeyColumn( columnName, "?" ); |
||||
} |
||||
return this; |
||||
} |
||||
|
||||
public Delete addPrimaryKeyColumns(String[] columnNames, boolean[] includeColumns, String[] valueExpressions) { |
||||
for ( int i=0; i<columnNames.length; i++ ) { |
||||
if( includeColumns[i] ) { |
||||
addPrimaryKeyColumn( columnNames[i], valueExpressions[i] ); |
||||
} |
||||
} |
||||
return this; |
||||
} |
||||
|
||||
public Delete addPrimaryKeyColumns(String[] columnNames, String[] valueExpressions) { |
||||
for ( int i=0; i<columnNames.length; i++ ) { |
||||
addPrimaryKeyColumn( columnNames[i], valueExpressions[i] ); |
||||
} |
||||
return this; |
||||
} |
||||
|
||||
public Delete addPrimaryKeyColumn(String columnName, String valueExpression) { |
||||
this.primaryKeyColumns.put(columnName, valueExpression); |
||||
return this; |
||||
} |
||||
|
||||
public Delete setVersionColumnName(String versionColumnName) { |
||||
this.versionColumnName = versionColumnName; |
||||
return this; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,121 @@
|
||||
/* |
||||
* Hibernate, Relational Persistence for Idiomatic Java |
||||
* |
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later. |
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/ |
||||
package com.fr.third.org.hibernate.sql; |
||||
import java.util.Iterator; |
||||
import java.util.LinkedHashMap; |
||||
import java.util.Map; |
||||
|
||||
import com.fr.third.org.hibernate.dialect.Dialect; |
||||
import com.fr.third.org.hibernate.type.LiteralType; |
||||
|
||||
/** |
||||
* An SQL <tt>INSERT</tt> statement |
||||
* |
||||
* @author Gavin King |
||||
*/ |
||||
public class Insert { |
||||
private Dialect dialect; |
||||
private String tableName; |
||||
private String comment; |
||||
private Map columns = new LinkedHashMap(); |
||||
|
||||
public Insert(Dialect dialect) { |
||||
this.dialect = dialect; |
||||
} |
||||
|
||||
protected Dialect getDialect() { |
||||
return dialect; |
||||
} |
||||
|
||||
public Insert setComment(String comment) { |
||||
this.comment = comment; |
||||
return this; |
||||
} |
||||
|
||||
public Insert addColumn(String columnName) { |
||||
return addColumn(columnName, "?"); |
||||
} |
||||
|
||||
public Insert addColumns(String[] columnNames) { |
||||
for ( int i=0; i<columnNames.length; i++ ) { |
||||
addColumn( columnNames[i] ); |
||||
} |
||||
return this; |
||||
} |
||||
|
||||
public Insert addColumns(String[] columnNames, boolean[] insertable) { |
||||
for ( int i=0; i<columnNames.length; i++ ) { |
||||
if ( insertable[i] ) { |
||||
addColumn( columnNames[i] ); |
||||
} |
||||
} |
||||
return this; |
||||
} |
||||
|
||||
public Insert addColumns(String[] columnNames, boolean[] insertable, String[] valueExpressions) { |
||||
for ( int i=0; i<columnNames.length; i++ ) { |
||||
if ( insertable[i] ) { |
||||
addColumn( columnNames[i], valueExpressions[i] ); |
||||
} |
||||
} |
||||
return this; |
||||
} |
||||
|
||||
public Insert addColumn(String columnName, String valueExpression) { |
||||
columns.put(columnName, valueExpression); |
||||
return this; |
||||
} |
||||
|
||||
public Insert addColumn(String columnName, Object value, LiteralType type) throws Exception { |
||||
return addColumn( columnName, type.objectToSQLString(value, dialect) ); |
||||
} |
||||
|
||||
public Insert addIdentityColumn(String columnName) { |
||||
String value = dialect.getIdentityColumnSupport().getIdentityInsertString(); |
||||
if ( value != null ) { |
||||
addColumn( columnName, value ); |
||||
} |
||||
return this; |
||||
} |
||||
|
||||
public Insert setTableName(String tableName) { |
||||
this.tableName = tableName; |
||||
return this; |
||||
} |
||||
|
||||
public String toStatementString() { |
||||
StringBuilder buf = new StringBuilder( columns.size()*15 + tableName.length() + 10 ); |
||||
if ( comment != null ) { |
||||
buf.append( "/* " ).append( Dialect.escapeComment(comment) ).append( " */ " ); |
||||
} |
||||
buf.append("insert into ") |
||||
.append(tableName); |
||||
if ( columns.size()==0 ) { |
||||
buf.append(' ').append( dialect.getNoColumnsInsertString() ); |
||||
} |
||||
else { |
||||
buf.append(" ("); |
||||
Iterator iter = columns.keySet().iterator(); |
||||
while ( iter.hasNext() ) { |
||||
buf.append( iter.next() ); |
||||
if ( iter.hasNext() ) { |
||||
buf.append( ", " ); |
||||
} |
||||
} |
||||
buf.append(") values ("); |
||||
iter = columns.values().iterator(); |
||||
while ( iter.hasNext() ) { |
||||
buf.append( iter.next() ); |
||||
if ( iter.hasNext() ) { |
||||
buf.append( ", " ); |
||||
} |
||||
} |
||||
buf.append(')'); |
||||
} |
||||
return buf.toString(); |
||||
} |
||||
} |
@ -0,0 +1,85 @@
|
||||
/* |
||||
* Hibernate, Relational Persistence for Idiomatic Java |
||||
* |
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later. |
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/ |
||||
package com.fr.third.org.hibernate.sql; |
||||
import java.util.ArrayList; |
||||
import java.util.Iterator; |
||||
import java.util.List; |
||||
|
||||
import com.fr.third.org.hibernate.HibernateException; |
||||
import com.fr.third.org.hibernate.dialect.Dialect; |
||||
|
||||
/** |
||||
* Implementation of InsertSelect. |
||||
* |
||||
* @author Steve Ebersole |
||||
*/ |
||||
public class InsertSelect { |
||||
private Dialect dialect; |
||||
private String tableName; |
||||
private String comment; |
||||
private List columnNames = new ArrayList(); |
||||
private Select select; |
||||
|
||||
public InsertSelect(Dialect dialect) { |
||||
this.dialect = dialect; |
||||
} |
||||
|
||||
public InsertSelect setTableName(String tableName) { |
||||
this.tableName = tableName; |
||||
return this; |
||||
} |
||||
|
||||
public InsertSelect setComment(String comment) { |
||||
this.comment = comment; |
||||
return this; |
||||
} |
||||
|
||||
public InsertSelect addColumn(String columnName) { |
||||
columnNames.add( columnName ); |
||||
return this; |
||||
} |
||||
|
||||
public InsertSelect addColumns(String[] columnNames) { |
||||
for ( int i = 0; i < columnNames.length; i++ ) { |
||||
this.columnNames.add( columnNames[i] ); |
||||
} |
||||
return this; |
||||
} |
||||
|
||||
public InsertSelect setSelect(Select select) { |
||||
this.select = select; |
||||
return this; |
||||
} |
||||
|
||||
public String toStatementString() { |
||||
if ( tableName == null ) { |
||||
throw new HibernateException( "no table name defined for insert-select" ); |
||||
} |
||||
if ( select == null ) { |
||||
throw new HibernateException( "no select defined for insert-select" ); |
||||
} |
||||
|
||||
StringBuilder buf = new StringBuilder( (columnNames.size() * 15) + tableName.length() + 10 ); |
||||
if ( comment!=null ) { |
||||
buf.append( "/* " ).append( Dialect.escapeComment(comment) ).append( " */ " ); |
||||
} |
||||
buf.append( "insert into " ).append( tableName ); |
||||
if ( !columnNames.isEmpty() ) { |
||||
buf.append( " (" ); |
||||
Iterator itr = columnNames.iterator(); |
||||
while ( itr.hasNext() ) { |
||||
buf.append( itr.next() ); |
||||
if ( itr.hasNext() ) { |
||||
buf.append( ", " ); |
||||
} |
||||
} |
||||
buf.append( ")" ); |
||||
} |
||||
buf.append( ' ' ).append( select.toStatementString() ); |
||||
return buf.toString(); |
||||
} |
||||
} |
@ -0,0 +1,215 @@
|
||||
/* |
||||
* Hibernate, Relational Persistence for Idiomatic Java |
||||
* |
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later. |
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/ |
||||
package com.fr.third.org.hibernate.sql; |
||||
|
||||
import java.util.HashSet; |
||||
import java.util.Iterator; |
||||
|
||||
import com.fr.third.org.hibernate.dialect.Dialect; |
||||
|
||||
/** |
||||
* A translated HQL query |
||||
* |
||||
* @author Gavin King |
||||
*/ |
||||
public class QuerySelect { |
||||
private Dialect dialect; |
||||
private JoinFragment joins; |
||||
private StringBuilder select = new StringBuilder(); |
||||
private StringBuilder where = new StringBuilder(); |
||||
private StringBuilder groupBy = new StringBuilder(); |
||||
private StringBuilder orderBy = new StringBuilder(); |
||||
private StringBuilder having = new StringBuilder(); |
||||
private String comment; |
||||
private boolean distinct; |
||||
|
||||
private static final HashSet<String> DONT_SPACE_TOKENS = new HashSet<String>(); |
||||
|
||||
static { |
||||
//dontSpace.add("'");
|
||||
DONT_SPACE_TOKENS.add( "." ); |
||||
DONT_SPACE_TOKENS.add( "+" ); |
||||
DONT_SPACE_TOKENS.add( "-" ); |
||||
DONT_SPACE_TOKENS.add( "/" ); |
||||
DONT_SPACE_TOKENS.add( "*" ); |
||||
DONT_SPACE_TOKENS.add( "<" ); |
||||
DONT_SPACE_TOKENS.add( ">" ); |
||||
DONT_SPACE_TOKENS.add( "=" ); |
||||
DONT_SPACE_TOKENS.add( "#" ); |
||||
DONT_SPACE_TOKENS.add( "~" ); |
||||
DONT_SPACE_TOKENS.add( "|" ); |
||||
DONT_SPACE_TOKENS.add( "&" ); |
||||
DONT_SPACE_TOKENS.add( "<=" ); |
||||
DONT_SPACE_TOKENS.add( ">=" ); |
||||
DONT_SPACE_TOKENS.add( "=>" ); |
||||
DONT_SPACE_TOKENS.add( "=<" ); |
||||
DONT_SPACE_TOKENS.add( "!=" ); |
||||
DONT_SPACE_TOKENS.add( "<>" ); |
||||
DONT_SPACE_TOKENS.add( "!#" ); |
||||
DONT_SPACE_TOKENS.add( "!~" ); |
||||
DONT_SPACE_TOKENS.add( "!<" ); |
||||
DONT_SPACE_TOKENS.add( "!>" ); |
||||
DONT_SPACE_TOKENS.add( "(" ); //for MySQL
|
||||
DONT_SPACE_TOKENS.add( ")" ); |
||||
} |
||||
|
||||
public QuerySelect(Dialect dialect) { |
||||
this.dialect = dialect; |
||||
joins = new QueryJoinFragment( dialect, false ); |
||||
} |
||||
|
||||
public JoinFragment getJoinFragment() { |
||||
return joins; |
||||
} |
||||
|
||||
public void addSelectFragmentString(String fragment) { |
||||
if ( fragment.length() > 0 && fragment.charAt( 0 ) == ',' ) { |
||||
fragment = fragment.substring( 1 ); |
||||
} |
||||
fragment = fragment.trim(); |
||||
if ( fragment.length() > 0 ) { |
||||
if ( select.length() > 0 ) { |
||||
select.append( ", " ); |
||||
} |
||||
select.append( fragment ); |
||||
} |
||||
} |
||||
|
||||
public void addSelectColumn(String columnName, String alias) { |
||||
addSelectFragmentString( columnName + ' ' + alias ); |
||||
} |
||||
|
||||
public void setDistinct(boolean distinct) { |
||||
this.distinct = distinct; |
||||
} |
||||
|
||||
public void setWhereTokens(Iterator tokens) { |
||||
//if ( conjunctiveWhere.length()>0 ) conjunctiveWhere.append(" and ");
|
||||
appendTokens( where, tokens ); |
||||
} |
||||
|
||||
public void prependWhereConditions(String conditions) { |
||||
if ( where.length() > 0 ) { |
||||
where.insert( 0, conditions + " and " ); |
||||
} |
||||
else { |
||||
where.append( conditions ); |
||||
} |
||||
} |
||||
|
||||
public void setGroupByTokens(Iterator tokens) { |
||||
//if ( groupBy.length()>0 ) groupBy.append(" and ");
|
||||
appendTokens( groupBy, tokens ); |
||||
} |
||||
|
||||
public void setOrderByTokens(Iterator tokens) { |
||||
//if ( orderBy.length()>0 ) orderBy.append(" and ");
|
||||
appendTokens( orderBy, tokens ); |
||||
} |
||||
|
||||
public void setHavingTokens(Iterator tokens) { |
||||
//if ( having.length()>0 ) having.append(" and ");
|
||||
appendTokens( having, tokens ); |
||||
} |
||||
|
||||
public void addOrderBy(String orderByString) { |
||||
if ( orderBy.length() > 0 ) { |
||||
orderBy.append( ", " ); |
||||
} |
||||
orderBy.append( orderByString ); |
||||
} |
||||
|
||||
public String toQueryString() { |
||||
StringBuilder buf = new StringBuilder( 50 ); |
||||
if ( comment != null ) { |
||||
buf.append( "/* " ).append( Dialect.escapeComment(comment) ).append( " */ " ); |
||||
} |
||||
buf.append( "select " ); |
||||
if ( distinct ) { |
||||
buf.append( "distinct " ); |
||||
} |
||||
String from = joins.toFromFragmentString(); |
||||
if ( from.startsWith( "," ) ) { |
||||
from = from.substring( 1 ); |
||||
} |
||||
else if ( from.startsWith( " inner join" ) ) { |
||||
from = from.substring( 11 ); |
||||
} |
||||
|
||||
buf.append( select.toString() ) |
||||
.append( " from" ) |
||||
.append( from ); |
||||
|
||||
String outerJoinsAfterWhere = joins.toWhereFragmentString().trim(); |
||||
String whereConditions = where.toString().trim(); |
||||
boolean hasOuterJoinsAfterWhere = outerJoinsAfterWhere.length() > 0; |
||||
boolean hasWhereConditions = whereConditions.length() > 0; |
||||
if ( hasOuterJoinsAfterWhere || hasWhereConditions ) { |
||||
buf.append( " where " ); |
||||
if ( hasOuterJoinsAfterWhere ) { |
||||
buf.append( outerJoinsAfterWhere.substring( 4 ) ); |
||||
} |
||||
if ( hasWhereConditions ) { |
||||
if ( hasOuterJoinsAfterWhere ) { |
||||
buf.append( " and (" ); |
||||
} |
||||
buf.append( whereConditions ); |
||||
if ( hasOuterJoinsAfterWhere ) { |
||||
buf.append( ")" ); |
||||
} |
||||
} |
||||
} |
||||
|
||||
if ( groupBy.length() > 0 ) { |
||||
buf.append( " group by " ).append( groupBy.toString() ); |
||||
} |
||||
if ( having.length() > 0 ) { |
||||
buf.append( " having " ).append( having.toString() ); |
||||
} |
||||
if ( orderBy.length() > 0 ) { |
||||
buf.append( " order by " ).append( orderBy.toString() ); |
||||
} |
||||
|
||||
return dialect.transformSelectString( buf.toString() ); |
||||
} |
||||
|
||||
private static void appendTokens(StringBuilder buf, Iterator iter) { |
||||
boolean lastSpaceable = true; |
||||
boolean lastQuoted = false; |
||||
while ( iter.hasNext() ) { |
||||
String token = (String) iter.next(); |
||||
boolean spaceable = !DONT_SPACE_TOKENS.contains( token ); |
||||
boolean quoted = token.startsWith( "'" ); |
||||
if ( spaceable && lastSpaceable ) { |
||||
if ( !quoted || !lastQuoted ) { |
||||
buf.append( ' ' ); |
||||
} |
||||
} |
||||
lastSpaceable = spaceable; |
||||
buf.append( token ); |
||||
lastQuoted = token.endsWith( "'" ); |
||||
} |
||||
} |
||||
|
||||
public void setComment(String comment) { |
||||
this.comment = comment; |
||||
} |
||||
|
||||
public QuerySelect copy() { |
||||
QuerySelect copy = new QuerySelect( dialect ); |
||||
copy.joins = this.joins.copy(); |
||||
copy.select.append( this.select.toString() ); |
||||
copy.where.append( this.where.toString() ); |
||||
copy.groupBy.append( this.groupBy.toString() ); |
||||
copy.orderBy.append( this.orderBy.toString() ); |
||||
copy.having.append( this.having.toString() ); |
||||
copy.comment = this.comment; |
||||
copy.distinct = this.distinct; |
||||
return copy; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,196 @@
|
||||
/* |
||||
* Hibernate, Relational Persistence for Idiomatic Java |
||||
* |
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later. |
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/ |
||||
package com.fr.third.org.hibernate.sql; |
||||
import com.fr.third.org.hibernate.LockMode; |
||||
import com.fr.third.org.hibernate.LockOptions; |
||||
import com.fr.third.org.hibernate.dialect.Dialect; |
||||
import com.fr.third.org.hibernate.internal.util.StringHelper; |
||||
|
||||
|
||||
/** |
||||
* A simple SQL <tt>SELECT</tt> statement |
||||
* @author Gavin King |
||||
*/ |
||||
public class Select { |
||||
|
||||
private String selectClause; |
||||
private String fromClause; |
||||
private String outerJoinsAfterFrom; |
||||
private String whereClause; |
||||
private String outerJoinsAfterWhere; |
||||
private String orderByClause; |
||||
private String groupByClause; |
||||
private String comment; |
||||
private LockOptions lockOptions = new LockOptions(); |
||||
public final Dialect dialect; |
||||
|
||||
private int guesstimatedBufferSize = 20; |
||||
|
||||
public Select(Dialect dialect) { |
||||
this.dialect = dialect; |
||||
} |
||||
|
||||
/** |
||||
* Construct an SQL <tt>SELECT</tt> statement from the given clauses |
||||
*/ |
||||
public String toStatementString() { |
||||
StringBuilder buf = new StringBuilder(guesstimatedBufferSize); |
||||
if ( StringHelper.isNotEmpty(comment) ) { |
||||
buf.append("/* ").append(Dialect.escapeComment(comment)).append(" */ "); |
||||
} |
||||
|
||||
buf.append("select ").append(selectClause) |
||||
.append(" from ").append(fromClause); |
||||
|
||||
if ( StringHelper.isNotEmpty(outerJoinsAfterFrom) ) { |
||||
buf.append(outerJoinsAfterFrom); |
||||
} |
||||
|
||||
if ( StringHelper.isNotEmpty(whereClause) || StringHelper.isNotEmpty(outerJoinsAfterWhere) ) { |
||||
buf.append(" where " ); |
||||
// the outerJoinsAfterWhere needs to come before where clause to properly
|
||||
// handle dynamic filters
|
||||
if ( StringHelper.isNotEmpty(outerJoinsAfterWhere) ) { |
||||
buf.append(outerJoinsAfterWhere); |
||||
if ( StringHelper.isNotEmpty(whereClause) ) { |
||||
buf.append( " and " ); |
||||
} |
||||
} |
||||
if ( StringHelper.isNotEmpty( whereClause ) ) { |
||||
buf.append(whereClause); |
||||
} |
||||
} |
||||
|
||||
if ( StringHelper.isNotEmpty(groupByClause) ) { |
||||
buf.append(" group by ").append(groupByClause); |
||||
} |
||||
|
||||
if ( StringHelper.isNotEmpty(orderByClause) ) { |
||||
buf.append(" order by ").append(orderByClause); |
||||
} |
||||
|
||||
if (lockOptions.getLockMode() != LockMode.NONE) { |
||||
buf.append(dialect.getForUpdateString(lockOptions)); |
||||
} |
||||
|
||||
return dialect.transformSelectString( buf.toString() ); |
||||
} |
||||
|
||||
/** |
||||
* Sets the fromClause. |
||||
* @param fromClause The fromClause to set |
||||
*/ |
||||
public Select setFromClause(String fromClause) { |
||||
this.fromClause = fromClause; |
||||
this.guesstimatedBufferSize += fromClause.length(); |
||||
return this; |
||||
} |
||||
|
||||
public Select setFromClause(String tableName, String alias) { |
||||
this.fromClause = tableName + ' ' + alias; |
||||
this.guesstimatedBufferSize += fromClause.length(); |
||||
return this; |
||||
} |
||||
|
||||
public Select setOrderByClause(String orderByClause) { |
||||
this.orderByClause = orderByClause; |
||||
this.guesstimatedBufferSize += orderByClause.length(); |
||||
return this; |
||||
} |
||||
|
||||
public Select setGroupByClause(String groupByClause) { |
||||
this.groupByClause = groupByClause; |
||||
this.guesstimatedBufferSize += groupByClause.length(); |
||||
return this; |
||||
} |
||||
|
||||
public Select setOuterJoins(String outerJoinsAfterFrom, String outerJoinsAfterWhere) { |
||||
this.outerJoinsAfterFrom = outerJoinsAfterFrom; |
||||
|
||||
// strip off any leading 'and' token
|
||||
String tmpOuterJoinsAfterWhere = outerJoinsAfterWhere.trim(); |
||||
if ( tmpOuterJoinsAfterWhere.startsWith("and") ) { |
||||
tmpOuterJoinsAfterWhere = tmpOuterJoinsAfterWhere.substring(4); |
||||
} |
||||
this.outerJoinsAfterWhere = tmpOuterJoinsAfterWhere; |
||||
|
||||
this.guesstimatedBufferSize += outerJoinsAfterFrom.length() + outerJoinsAfterWhere.length(); |
||||
return this; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Sets the selectClause. |
||||
* @param selectClause The selectClause to set |
||||
*/ |
||||
public Select setSelectClause(String selectClause) { |
||||
this.selectClause = selectClause; |
||||
this.guesstimatedBufferSize += selectClause.length(); |
||||
return this; |
||||
} |
||||
|
||||
public Select setSelectClause(SelectFragment selectFragment) { |
||||
setSelectClause( selectFragment.toFragmentString().substring( 2 ) ); |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* Sets the whereClause. |
||||
* @param whereClause The whereClause to set |
||||
*/ |
||||
public Select setWhereClause(String whereClause) { |
||||
this.whereClause = whereClause; |
||||
this.guesstimatedBufferSize += whereClause.length(); |
||||
return this; |
||||
} |
||||
|
||||
public Select setComment(String comment) { |
||||
this.comment = comment; |
||||
this.guesstimatedBufferSize += comment.length(); |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* Get the current lock mode |
||||
* @return LockMode |
||||
* @deprecated Instead use getLockOptions |
||||
*/ |
||||
@Deprecated |
||||
public LockMode getLockMode() { |
||||
return lockOptions.getLockMode(); |
||||
} |
||||
|
||||
/** |
||||
* Set the lock mode |
||||
* @param lockMode |
||||
* @return this object |
||||
* @deprecated Instead use setLockOptions |
||||
*/ |
||||
@Deprecated |
||||
public Select setLockMode(LockMode lockMode) { |
||||
lockOptions.setLockMode(lockMode); |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* Get the current lock options |
||||
* @return LockOptions |
||||
*/ |
||||
public LockOptions getLockOptions() { |
||||
return lockOptions; |
||||
} |
||||
|
||||
/** |
||||
* Set the lock options |
||||
* @param lockOptions |
||||
* @return this object |
||||
*/ |
||||
public Select setLockOptions(LockOptions lockOptions) { |
||||
LockOptions.copy(lockOptions, this.lockOptions); |
||||
return this; |
||||
} |
||||
} |
@ -0,0 +1,210 @@
|
||||
/* |
||||
* Hibernate, Relational Persistence for Idiomatic Java |
||||
* |
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later. |
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/ |
||||
package com.fr.third.org.hibernate.sql; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.HashMap; |
||||
import java.util.HashSet; |
||||
import java.util.Iterator; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
import java.util.Set; |
||||
|
||||
import com.fr.third.org.hibernate.LockMode; |
||||
import com.fr.third.org.hibernate.LockOptions; |
||||
import com.fr.third.org.hibernate.dialect.Dialect; |
||||
|
||||
/** |
||||
* An SQL <tt>SELECT</tt> statement with no table joins |
||||
* |
||||
* @author Gavin King |
||||
*/ |
||||
public class SimpleSelect { |
||||
|
||||
public SimpleSelect(Dialect dialect) { |
||||
this.dialect = dialect; |
||||
} |
||||
|
||||
//private static final Alias DEFAULT_ALIAS = new Alias(10, null);
|
||||
|
||||
private String tableName; |
||||
private String orderBy; |
||||
private Dialect dialect; |
||||
private LockOptions lockOptions = new LockOptions( LockMode.READ ); |
||||
private String comment; |
||||
|
||||
private List<String> columns = new ArrayList<String>(); |
||||
private Map<String, String> aliases = new HashMap<String, String>(); |
||||
private List<String> whereTokens = new ArrayList<String>(); |
||||
|
||||
public SimpleSelect addColumns(String[] columnNames, String[] columnAliases) { |
||||
for ( int i = 0; i < columnNames.length; i++ ) { |
||||
if ( columnNames[i] != null ) { |
||||
addColumn( columnNames[i], columnAliases[i] ); |
||||
} |
||||
} |
||||
return this; |
||||
} |
||||
|
||||
public SimpleSelect addColumns(String[] columns, String[] aliases, boolean[] ignore) { |
||||
for ( int i = 0; i < ignore.length; i++ ) { |
||||
if ( !ignore[i] && columns[i] != null ) { |
||||
addColumn( columns[i], aliases[i] ); |
||||
} |
||||
} |
||||
return this; |
||||
} |
||||
|
||||
public SimpleSelect addColumns(String[] columnNames) { |
||||
for ( String columnName : columnNames ) { |
||||
if ( columnName != null ) { |
||||
addColumn( columnName ); |
||||
} |
||||
} |
||||
return this; |
||||
} |
||||
|
||||
public SimpleSelect addColumn(String columnName) { |
||||
columns.add( columnName ); |
||||
//aliases.put( columnName, DEFAULT_ALIAS.toAliasString(columnName) );
|
||||
return this; |
||||
} |
||||
|
||||
public SimpleSelect addColumn(String columnName, String alias) { |
||||
columns.add( columnName ); |
||||
aliases.put( columnName, alias ); |
||||
return this; |
||||
} |
||||
|
||||
public SimpleSelect setTableName(String tableName) { |
||||
this.tableName = tableName; |
||||
return this; |
||||
} |
||||
|
||||
public SimpleSelect setLockOptions(LockOptions lockOptions) { |
||||
LockOptions.copy( lockOptions, this.lockOptions ); |
||||
return this; |
||||
} |
||||
|
||||
public SimpleSelect setLockMode(LockMode lockMode) { |
||||
this.lockOptions.setLockMode( lockMode ); |
||||
return this; |
||||
} |
||||
|
||||
public SimpleSelect addWhereToken(String token) { |
||||
whereTokens.add( token ); |
||||
return this; |
||||
} |
||||
|
||||
private void and() { |
||||
if ( whereTokens.size() > 0 ) { |
||||
whereTokens.add( "and" ); |
||||
} |
||||
} |
||||
|
||||
public SimpleSelect addCondition(String lhs, String op, String rhs) { |
||||
and(); |
||||
whereTokens.add( lhs + ' ' + op + ' ' + rhs ); |
||||
return this; |
||||
} |
||||
|
||||
public SimpleSelect addCondition(String lhs, String condition) { |
||||
and(); |
||||
whereTokens.add( lhs + ' ' + condition ); |
||||
return this; |
||||
} |
||||
|
||||
public SimpleSelect addCondition(String[] lhs, String op, String[] rhs) { |
||||
for ( int i = 0; i < lhs.length; i++ ) { |
||||
addCondition( lhs[i], op, rhs[i] ); |
||||
} |
||||
return this; |
||||
} |
||||
|
||||
public SimpleSelect addCondition(String[] lhs, String condition) { |
||||
for ( String lh : lhs ) { |
||||
if ( lh != null ) { |
||||
addCondition( lh, condition ); |
||||
} |
||||
} |
||||
return this; |
||||
} |
||||
|
||||
public String toStatementString() { |
||||
StringBuilder buf = new StringBuilder( |
||||
columns.size() * 10 + |
||||
tableName.length() + |
||||
whereTokens.size() * 10 + |
||||
10 |
||||
); |
||||
|
||||
if ( comment != null ) { |
||||
buf.append( "/* " ).append( Dialect.escapeComment(comment) ).append( " */ " ); |
||||
} |
||||
|
||||
buf.append( "select " ); |
||||
Set<String> uniqueColumns = new HashSet<String>(); |
||||
Iterator<String> iter = columns.iterator(); |
||||
boolean appendComma = false; |
||||
while ( iter.hasNext() ) { |
||||
String col = iter.next(); |
||||
String alias = aliases.get( col ); |
||||
if ( uniqueColumns.add( alias == null ? col : alias ) ) { |
||||
if ( appendComma ) { |
||||
buf.append( ", " ); |
||||
} |
||||
buf.append( col ); |
||||
if ( alias != null && !alias.equals( col ) ) { |
||||
buf.append( " as " ) |
||||
.append( alias ); |
||||
} |
||||
appendComma = true; |
||||
} |
||||
} |
||||
|
||||
buf.append( " from " ) |
||||
.append( dialect.appendLockHint( lockOptions, tableName ) ); |
||||
|
||||
if ( whereTokens.size() > 0 ) { |
||||
buf.append( " where " ) |
||||
.append( toWhereClause() ); |
||||
} |
||||
|
||||
if ( orderBy != null ) { |
||||
buf.append( orderBy ); |
||||
} |
||||
|
||||
if ( lockOptions != null ) { |
||||
buf = new StringBuilder(dialect.applyLocksToSql( buf.toString(), lockOptions, null ) ); |
||||
} |
||||
|
||||
return dialect.transformSelectString( buf.toString() ); |
||||
} |
||||
|
||||
public String toWhereClause() { |
||||
StringBuilder buf = new StringBuilder( whereTokens.size() * 5 ); |
||||
Iterator<String> iter = whereTokens.iterator(); |
||||
while ( iter.hasNext() ) { |
||||
buf.append( iter.next() ); |
||||
if ( iter.hasNext() ) { |
||||
buf.append( ' ' ); |
||||
} |
||||
} |
||||
return buf.toString(); |
||||
} |
||||
|
||||
public SimpleSelect setOrderBy(String orderBy) { |
||||
this.orderBy = orderBy; |
||||
return this; |
||||
} |
||||
|
||||
public SimpleSelect setComment(String comment) { |
||||
this.comment = comment; |
||||
return this; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,227 @@
|
||||
/* |
||||
* Hibernate, Relational Persistence for Idiomatic Java |
||||
* |
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later. |
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/ |
||||
package com.fr.third.org.hibernate.sql; |
||||
import java.util.Iterator; |
||||
import java.util.LinkedHashMap; |
||||
import java.util.Map; |
||||
|
||||
import com.fr.third.org.hibernate.dialect.Dialect; |
||||
import com.fr.third.org.hibernate.type.LiteralType; |
||||
|
||||
/** |
||||
* An SQL <tt>UPDATE</tt> statement |
||||
* |
||||
* @author Gavin King |
||||
*/ |
||||
public class Update { |
||||
|
||||
private String tableName; |
||||
private String versionColumnName; |
||||
private String where; |
||||
private String assignments; |
||||
private String comment; |
||||
|
||||
private Map primaryKeyColumns = new LinkedHashMap(); |
||||
private Map columns = new LinkedHashMap(); |
||||
private Map whereColumns = new LinkedHashMap(); |
||||
|
||||
private Dialect dialect; |
||||
|
||||
public Update(Dialect dialect) { |
||||
this.dialect = dialect; |
||||
} |
||||
|
||||
public String getTableName() { |
||||
return tableName; |
||||
} |
||||
|
||||
public Update appendAssignmentFragment(String fragment) { |
||||
if ( assignments == null ) { |
||||
assignments = fragment; |
||||
} |
||||
else { |
||||
assignments += ", " + fragment; |
||||
} |
||||
return this; |
||||
} |
||||
|
||||
public Update setTableName(String tableName) { |
||||
this.tableName = tableName; |
||||
return this; |
||||
} |
||||
|
||||
public Update setPrimaryKeyColumnNames(String[] columnNames) { |
||||
this.primaryKeyColumns.clear(); |
||||
addPrimaryKeyColumns(columnNames); |
||||
return this; |
||||
} |
||||
|
||||
public Update addPrimaryKeyColumns(String[] columnNames) { |
||||
for ( String columnName : columnNames ) { |
||||
addPrimaryKeyColumn( columnName, "?" ); |
||||
} |
||||
return this; |
||||
} |
||||
|
||||
public Update addPrimaryKeyColumns(String[] columnNames, boolean[] includeColumns, String[] valueExpressions) { |
||||
for ( int i=0; i<columnNames.length; i++ ) { |
||||
if( includeColumns[i] ) { |
||||
addPrimaryKeyColumn( columnNames[i], valueExpressions[i] ); |
||||
} |
||||
} |
||||
return this; |
||||
} |
||||
|
||||
public Update addPrimaryKeyColumns(String[] columnNames, String[] valueExpressions) { |
||||
for ( int i=0; i<columnNames.length; i++ ) { |
||||
addPrimaryKeyColumn( columnNames[i], valueExpressions[i] ); |
||||
} |
||||
return this; |
||||
} |
||||
|
||||
public Update addPrimaryKeyColumn(String columnName, String valueExpression) { |
||||
this.primaryKeyColumns.put(columnName, valueExpression); |
||||
return this; |
||||
} |
||||
|
||||
public Update setVersionColumnName(String versionColumnName) { |
||||
this.versionColumnName = versionColumnName; |
||||
return this; |
||||
} |
||||
|
||||
|
||||
public Update setComment(String comment) { |
||||
this.comment = comment; |
||||
return this; |
||||
} |
||||
|
||||
public Update addColumns(String[] columnNames) { |
||||
for ( String columnName : columnNames ) { |
||||
addColumn( columnName ); |
||||
} |
||||
return this; |
||||
} |
||||
|
||||
public Update addColumns(String[] columnNames, boolean[] updateable, String[] valueExpressions) { |
||||
for ( int i=0; i<columnNames.length; i++ ) { |
||||
if ( updateable[i] ) { |
||||
addColumn( columnNames[i], valueExpressions[i] ); |
||||
} |
||||
} |
||||
return this; |
||||
} |
||||
|
||||
public Update addColumns(String[] columnNames, String valueExpression) { |
||||
for ( String columnName : columnNames ) { |
||||
addColumn( columnName, valueExpression ); |
||||
} |
||||
return this; |
||||
} |
||||
|
||||
public Update addColumn(String columnName) { |
||||
return addColumn(columnName, "?"); |
||||
} |
||||
|
||||
public Update addColumn(String columnName, String valueExpression) { |
||||
columns.put(columnName, valueExpression); |
||||
return this; |
||||
} |
||||
|
||||
public Update addColumn(String columnName, Object value, LiteralType type) throws Exception { |
||||
return addColumn( columnName, type.objectToSQLString(value, dialect) ); |
||||
} |
||||
|
||||
public Update addWhereColumns(String[] columnNames) { |
||||
for ( String columnName : columnNames ) { |
||||
addWhereColumn( columnName ); |
||||
} |
||||
return this; |
||||
} |
||||
|
||||
public Update addWhereColumns(String[] columnNames, String valueExpression) { |
||||
for ( String columnName : columnNames ) { |
||||
addWhereColumn( columnName, valueExpression ); |
||||
} |
||||
return this; |
||||
} |
||||
|
||||
public Update addWhereColumn(String columnName) { |
||||
return addWhereColumn(columnName, "=?"); |
||||
} |
||||
|
||||
public Update addWhereColumn(String columnName, String valueExpression) { |
||||
whereColumns.put(columnName, valueExpression); |
||||
return this; |
||||
} |
||||
|
||||
public Update setWhere(String where) { |
||||
this.where=where; |
||||
return this; |
||||
} |
||||
|
||||
public String toStatementString() { |
||||
StringBuilder buf = new StringBuilder( (columns.size() * 15) + tableName.length() + 10 ); |
||||
if ( comment!=null ) { |
||||
buf.append( "/* " ).append( Dialect.escapeComment(comment) ).append( " */ " ); |
||||
} |
||||
buf.append( "update " ).append( tableName ).append( " set " ); |
||||
boolean assignmentsAppended = false; |
||||
Iterator iter = columns.entrySet().iterator(); |
||||
while ( iter.hasNext() ) { |
||||
Map.Entry e = (Map.Entry) iter.next(); |
||||
buf.append( e.getKey() ).append( '=' ).append( e.getValue() ); |
||||
if ( iter.hasNext() ) { |
||||
buf.append( ", " ); |
||||
} |
||||
assignmentsAppended = true; |
||||
} |
||||
if ( assignments != null ) { |
||||
if ( assignmentsAppended ) { |
||||
buf.append( ", " ); |
||||
} |
||||
buf.append( assignments ); |
||||
} |
||||
|
||||
boolean conditionsAppended = false; |
||||
if ( !primaryKeyColumns.isEmpty() || where != null || !whereColumns.isEmpty() || versionColumnName != null ) { |
||||
buf.append( " where " ); |
||||
} |
||||
iter = primaryKeyColumns.entrySet().iterator(); |
||||
while ( iter.hasNext() ) { |
||||
Map.Entry e = (Map.Entry) iter.next(); |
||||
buf.append( e.getKey() ).append( '=' ).append( e.getValue() ); |
||||
if ( iter.hasNext() ) { |
||||
buf.append( " and " ); |
||||
} |
||||
conditionsAppended = true; |
||||
} |
||||
if ( where != null ) { |
||||
if ( conditionsAppended ) { |
||||
buf.append( " and " ); |
||||
} |
||||
buf.append( where ); |
||||
conditionsAppended = true; |
||||
} |
||||
iter = whereColumns.entrySet().iterator(); |
||||
while ( iter.hasNext() ) { |
||||
final Map.Entry e = (Map.Entry) iter.next(); |
||||
if ( conditionsAppended ) { |
||||
buf.append( " and " ); |
||||
} |
||||
buf.append( e.getKey() ).append( e.getValue() ); |
||||
conditionsAppended = true; |
||||
} |
||||
if ( versionColumnName != null ) { |
||||
if ( conditionsAppended ) { |
||||
buf.append( " and " ); |
||||
} |
||||
buf.append( versionColumnName ).append( "=?" ); |
||||
} |
||||
|
||||
return buf.toString(); |
||||
} |
||||
} |
Binary file not shown.
@ -1,121 +0,0 @@
|
||||
/* |
||||
* Copyright 2004-2005 OpenSymphony |
||||
* |
||||
* 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. |
||||
* |
||||
*/ |
||||
|
||||
/* |
||||
* Previously Copyright (c) 2001-2004 James House |
||||
*/ |
||||
package org.quartz.jobs; |
||||
|
||||
import java.io.File; |
||||
|
||||
import org.quartz.JobDataMap; |
||||
import org.quartz.JobExecutionContext; |
||||
import org.quartz.JobExecutionException; |
||||
import org.quartz.SchedulerContext; |
||||
import org.quartz.SchedulerException; |
||||
import org.quartz.StatefulJob; |
||||
|
||||
import org.apache.commons.logging.Log; |
||||
import org.apache.commons.logging.LogFactory; |
||||
|
||||
/** |
||||
* Inspects a file and compares whether it's "last modified date" has changed |
||||
* since the last time it was inspected. If the file has been updated, the |
||||
* job invokes a "call-back" method on an identified |
||||
* <code>FileScanListener</code> that can be found in the |
||||
* <code>SchedulerContext</code>. |
||||
* |
||||
* @author jhouse |
||||
* @see org.quartz.jobs.FileScanListener |
||||
*/ |
||||
public class FileScanJob implements StatefulJob { |
||||
|
||||
public static String FILE_NAME = "FILE_NAME"; |
||||
public static String FILE_SCAN_LISTENER_NAME = "FILE_SCAN_LISTENER_NAME"; |
||||
private static String LAST_MODIFIED_TIME = "LAST_MODIFIED_TIME"; |
||||
|
||||
private final Log log = LogFactory.getLog(getClass()); |
||||
|
||||
public FileScanJob() { |
||||
} |
||||
|
||||
/** |
||||
* @see org.quartz.Job#execute(org.quartz.JobExecutionContext) |
||||
*/ |
||||
public void execute(JobExecutionContext context) throws JobExecutionException { |
||||
JobDataMap mergedJobDataMap = context.getMergedJobDataMap(); |
||||
SchedulerContext schedCtxt = null; |
||||
try { |
||||
schedCtxt = context.getScheduler().getContext(); |
||||
} catch (SchedulerException e) { |
||||
throw new JobExecutionException("Error obtaining scheduler context.", e, false); |
||||
} |
||||
|
||||
String fileName = mergedJobDataMap.getString(FILE_NAME); |
||||
String listenerName = mergedJobDataMap.getString(FILE_SCAN_LISTENER_NAME); |
||||
|
||||
if(fileName == null) { |
||||
throw new JobExecutionException("Required parameter '" + |
||||
FILE_NAME + "' not found in merged JobDataMap"); |
||||
} |
||||
if(listenerName == null) { |
||||
throw new JobExecutionException("Required parameter '" + |
||||
FILE_SCAN_LISTENER_NAME + "' not found in merged JobDataMap"); |
||||
} |
||||
|
||||
FileScanListener listener = (FileScanListener)schedCtxt.get(listenerName); |
||||
|
||||
if(listener == null) { |
||||
throw new JobExecutionException("FileScanListener named '" + |
||||
listenerName + "' not found in SchedulerContext"); |
||||
} |
||||
|
||||
long lastDate = -1; |
||||
if(mergedJobDataMap.containsKey(LAST_MODIFIED_TIME)) { |
||||
lastDate = mergedJobDataMap.getLong(LAST_MODIFIED_TIME); |
||||
} |
||||
|
||||
long newDate = getLastModifiedDate(fileName); |
||||
|
||||
if(newDate < 0) { |
||||
log.warn("File '"+fileName+"' does not exist."); |
||||
return; |
||||
} |
||||
|
||||
if(lastDate > 0 && (newDate != lastDate)) { |
||||
// notify call back...
|
||||
log.info("File '"+fileName+"' updated, notifying listener."); |
||||
listener.fileUpdated(fileName); |
||||
} else if (log.isDebugEnabled()) { |
||||
log.debug("File '"+fileName+"' unchanged."); |
||||
} |
||||
|
||||
// It is the JobDataMap on the JobDetail which is actually stateful
|
||||
context.getJobDetail().getJobDataMap().put(LAST_MODIFIED_TIME, newDate); |
||||
} |
||||
|
||||
protected long getLastModifiedDate(String fileName) { |
||||
|
||||
File file = new File(fileName); |
||||
|
||||
if(!file.exists()) { |
||||
return -1; |
||||
} else { |
||||
return file.lastModified(); |
||||
} |
||||
} |
||||
} |
@ -1,202 +0,0 @@
|
||||
/* |
||||
* Copyright 2004-2005 OpenSymphony |
||||
* |
||||
* 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. |
||||
* |
||||
*/ |
||||
|
||||
/* |
||||
* Previously Copyright (c) 2001-2004 James House |
||||
*/ |
||||
package org.quartz.simpl; |
||||
|
||||
import java.util.Iterator; |
||||
import java.util.LinkedList; |
||||
import java.net.URL; |
||||
import java.io.InputStream; |
||||
|
||||
import org.quartz.spi.ClassLoadHelper; |
||||
|
||||
/** |
||||
* A <code>ClassLoadHelper</code> uses all of the <code>ClassLoadHelper</code> |
||||
* types that are found in this package in its attempts to load a class, when |
||||
* one scheme is found to work, it is promoted to the scheme that will be used |
||||
* first the next time a class is loaded (in order to improve perfomance). |
||||
* |
||||
* <p> |
||||
* This approach is used because of the wide variance in class loader behavior |
||||
* between the various environments in which Quartz runs (e.g. disparate |
||||
* application servers, stand-alone, mobile devices, etc.). Because of this |
||||
* disparity, Quartz ran into difficulty with a one class-load style fits-all |
||||
* design. Thus, this class loader finds the approach that works, then |
||||
* 'remembers' it. |
||||
* </p> |
||||
* |
||||
* @see org.quartz.spi.ClassLoadHelper |
||||
* @see org.quartz.simpl.LoadingLoaderClassLoadHelper |
||||
* @see org.quartz.simpl.SimpleClassLoadHelper |
||||
* @see org.quartz.simpl.ThreadContextClassLoadHelper |
||||
* @see org.quartz.simpl.InitThreadContextClassLoadHelper |
||||
* |
||||
* @author jhouse |
||||
*/ |
||||
public class CascadingClassLoadHelper implements ClassLoadHelper { |
||||
|
||||
|
||||
/* |
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
||||
* |
||||
* Data members. |
||||
* |
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
||||
*/ |
||||
|
||||
private LinkedList loadHelpers; |
||||
|
||||
private ClassLoadHelper bestCandidate; |
||||
|
||||
/* |
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
||||
* |
||||
* Interface. |
||||
* |
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
||||
*/ |
||||
|
||||
/** |
||||
* Called to give the ClassLoadHelper a chance to initialize itself, |
||||
* including the oportunity to "steal" the class loader off of the calling |
||||
* thread, which is the thread that is initializing Quartz. |
||||
*/ |
||||
public void initialize() { |
||||
loadHelpers = new LinkedList(); |
||||
|
||||
loadHelpers.add(new LoadingLoaderClassLoadHelper()); |
||||
loadHelpers.add(new SimpleClassLoadHelper()); |
||||
loadHelpers.add(new ThreadContextClassLoadHelper()); |
||||
loadHelpers.add(new InitThreadContextClassLoadHelper()); |
||||
|
||||
Iterator iter = loadHelpers.iterator(); |
||||
while (iter.hasNext()) { |
||||
ClassLoadHelper loadHelper = (ClassLoadHelper) iter.next(); |
||||
loadHelper.initialize(); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Return the class with the given name. |
||||
*/ |
||||
public Class loadClass(String name) throws ClassNotFoundException { |
||||
|
||||
if (bestCandidate != null) { |
||||
try { |
||||
return bestCandidate.loadClass(name); |
||||
} catch (Exception e) { |
||||
bestCandidate = null; |
||||
} |
||||
} |
||||
|
||||
ClassNotFoundException cnfe = null; |
||||
Class clazz = null; |
||||
ClassLoadHelper loadHelper = null; |
||||
|
||||
Iterator iter = loadHelpers.iterator(); |
||||
while (iter.hasNext()) { |
||||
loadHelper = (ClassLoadHelper) iter.next(); |
||||
|
||||
try { |
||||
clazz = loadHelper.loadClass(name); |
||||
break; |
||||
} catch (ClassNotFoundException e) { |
||||
cnfe = e; |
||||
} |
||||
} |
||||
|
||||
if (clazz == null) { |
||||
throw cnfe; |
||||
} |
||||
|
||||
bestCandidate = loadHelper; |
||||
|
||||
return clazz; |
||||
} |
||||
|
||||
/** |
||||
* Finds a resource with a given name. This method returns null if no |
||||
* resource with this name is found. |
||||
* @param name name of the desired resource |
||||
* @return a java.net.URL object |
||||
*/ |
||||
public URL getResource(String name) { |
||||
|
||||
if (bestCandidate != null) { |
||||
try { |
||||
return bestCandidate.getResource(name); |
||||
} catch (Exception e) { |
||||
bestCandidate = null; |
||||
} |
||||
} |
||||
|
||||
URL result = null; |
||||
ClassLoadHelper loadHelper = null; |
||||
|
||||
Iterator iter = loadHelpers.iterator(); |
||||
while (iter.hasNext()) { |
||||
loadHelper = (ClassLoadHelper) iter.next(); |
||||
|
||||
result = loadHelper.getResource(name); |
||||
if (result != null) { |
||||
break; |
||||
} |
||||
} |
||||
|
||||
bestCandidate = loadHelper; |
||||
return result; |
||||
|
||||
} |
||||
|
||||
/** |
||||
* Finds a resource with a given name. This method returns null if no |
||||
* resource with this name is found. |
||||
* @param name name of the desired resource |
||||
* @return a java.io.InputStream object |
||||
*/ |
||||
public InputStream getResourceAsStream(String name) { |
||||
|
||||
if (bestCandidate != null) { |
||||
try { |
||||
return bestCandidate.getResourceAsStream(name); |
||||
} catch (Exception e) { |
||||
bestCandidate = null; |
||||
} |
||||
} |
||||
|
||||
InputStream result = null; |
||||
ClassLoadHelper loadHelper = null; |
||||
|
||||
Iterator iter = loadHelpers.iterator(); |
||||
while (iter.hasNext()) { |
||||
loadHelper = (ClassLoadHelper) iter.next(); |
||||
|
||||
result = loadHelper.getResourceAsStream(name); |
||||
if (result != null) { |
||||
break; |
||||
} |
||||
} |
||||
|
||||
bestCandidate = loadHelper; |
||||
return result; |
||||
|
||||
} |
||||
|
||||
} |
@ -1,96 +0,0 @@
|
||||
/* |
||||
* Copyright 2004-2005 OpenSymphony |
||||
* |
||||
* 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. |
||||
* |
||||
*/ |
||||
|
||||
/* |
||||
* Previously Copyright (c) 2001-2004 James House |
||||
*/ |
||||
package org.quartz.simpl; |
||||
|
||||
import org.quartz.spi.ClassLoadHelper; |
||||
|
||||
import java.net.URL; |
||||
import java.io.InputStream; |
||||
|
||||
/** |
||||
* A <code>ClassLoadHelper</code> that uses either the context class loader |
||||
* of the thread that initialized Quartz. |
||||
* |
||||
* @see org.quartz.spi.ClassLoadHelper |
||||
* @see org.quartz.simpl.ThreadContextClassLoadHelper |
||||
* @see org.quartz.simpl.SimpleClassLoadHelper |
||||
* @see org.quartz.simpl.CascadingClassLoadHelper |
||||
* @see org.quartz.simpl.LoadingLoaderClassLoadHelper |
||||
* |
||||
* @author jhouse |
||||
*/ |
||||
public class InitThreadContextClassLoadHelper implements ClassLoadHelper { |
||||
|
||||
|
||||
/* |
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
||||
* |
||||
* Data members. |
||||
* |
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
||||
*/ |
||||
|
||||
private ClassLoader initClassLoader; |
||||
|
||||
/* |
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
||||
* |
||||
* Interface. |
||||
* |
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
||||
*/ |
||||
|
||||
/** |
||||
* Called to give the ClassLoadHelper a chance to initialize itself, |
||||
* including the oportunity to "steal" the class loader off of the calling |
||||
* thread, which is the thread that is initializing Quartz. |
||||
*/ |
||||
public void initialize() { |
||||
initClassLoader = Thread.currentThread().getContextClassLoader(); |
||||
} |
||||
|
||||
/** |
||||
* Return the class with the given name. |
||||
*/ |
||||
public Class loadClass(String name) throws ClassNotFoundException { |
||||
return initClassLoader.loadClass(name); |
||||
} |
||||
|
||||
/** |
||||
* Finds a resource with a given name. This method returns null if no |
||||
* resource with this name is found. |
||||
* @param name name of the desired resource |
||||
* @return a java.net.URL object |
||||
*/ |
||||
public URL getResource(String name) { |
||||
return initClassLoader.getResource(name); |
||||
} |
||||
|
||||
/** |
||||
* Finds a resource with a given name. This method returns null if no |
||||
* resource with this name is found. |
||||
* @param name name of the desired resource |
||||
* @return a java.io.InputStream object |
||||
*/ |
||||
public InputStream getResourceAsStream(String name) { |
||||
return initClassLoader.getResourceAsStream(name); |
||||
} |
||||
} |
@ -1,87 +0,0 @@
|
||||
/* |
||||
* Copyright 2004-2005 OpenSymphony |
||||
* |
||||
* 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. |
||||
* |
||||
*/ |
||||
|
||||
/* |
||||
* Previously Copyright (c) 2001-2004 James House |
||||
*/ |
||||
package org.quartz.simpl; |
||||
|
||||
import org.quartz.spi.ClassLoadHelper; |
||||
|
||||
import java.net.URL; |
||||
import java.io.InputStream; |
||||
|
||||
/** |
||||
* A <code>ClassLoadHelper</code> that uses either the loader of it's own |
||||
* class (<code>this.getClass().getClassLoader().loadClass( .. )</code>). |
||||
* |
||||
* @see org.quartz.spi.ClassLoadHelper |
||||
* @see org.quartz.simpl.InitThreadContextClassLoadHelper |
||||
* @see org.quartz.simpl.SimpleClassLoadHelper |
||||
* @see org.quartz.simpl.CascadingClassLoadHelper |
||||
* |
||||
* @author jhouse |
||||
*/ |
||||
public class LoadingLoaderClassLoadHelper implements ClassLoadHelper { |
||||
|
||||
/* |
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
||||
* |
||||
* Interface. |
||||
* |
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
||||
*/ |
||||
|
||||
/** |
||||
* Called to give the ClassLoadHelper a chance to initialize itself, |
||||
* including the oportunity to "steal" the class loader off of the calling |
||||
* thread, which is the thread that is initializing Quartz. |
||||
*/ |
||||
public void initialize() { |
||||
} |
||||
|
||||
/** |
||||
* Return the class with the given name. |
||||
*/ |
||||
public Class loadClass(String name) throws ClassNotFoundException { |
||||
return getClassLoader().loadClass(name); |
||||
} |
||||
|
||||
/** |
||||
* Finds a resource with a given name. This method returns null if no |
||||
* resource with this name is found. |
||||
* @param name name of the desired resource |
||||
* @return a java.net.URL object |
||||
*/ |
||||
public URL getResource(String name) { |
||||
return getClassLoader().getResource(name); |
||||
} |
||||
|
||||
/** |
||||
* Finds a resource with a given name. This method returns null if no |
||||
* resource with this name is found. |
||||
* @param name name of the desired resource |
||||
* @return a java.io.InputStream object |
||||
*/ |
||||
public InputStream getResourceAsStream(String name) { |
||||
return getClassLoader().getResourceAsStream(name); |
||||
} |
||||
|
||||
private ClassLoader getClassLoader() { |
||||
return this.getClass().getClassLoader(); |
||||
} |
||||
} |
@ -1,106 +0,0 @@
|
||||
/* |
||||
* Copyright 2004-2005 OpenSymphony |
||||
* |
||||
* 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. |
||||
* |
||||
*/ |
||||
|
||||
/* |
||||
* Previously Copyright (c) 2001-2004 James House |
||||
*/ |
||||
package org.quartz.simpl; |
||||
|
||||
import org.quartz.spi.ClassLoadHelper; |
||||
|
||||
import java.lang.reflect.AccessibleObject; |
||||
import java.lang.reflect.Method; |
||||
import java.net.URL; |
||||
import java.io.InputStream; |
||||
|
||||
/** |
||||
* A <code>ClassLoadHelper</code> that simply calls <code>Class.forName(..)</code>. |
||||
* |
||||
* @see org.quartz.spi.ClassLoadHelper |
||||
* @see org.quartz.simpl.ThreadContextClassLoadHelper |
||||
* @see org.quartz.simpl.CascadingClassLoadHelper |
||||
* @see org.quartz.simpl.LoadingLoaderClassLoadHelper |
||||
* |
||||
* @author jhouse |
||||
*/ |
||||
public class SimpleClassLoadHelper implements ClassLoadHelper { |
||||
|
||||
/* |
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
||||
* |
||||
* Interface. |
||||
* |
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
||||
*/ |
||||
|
||||
/** |
||||
* Called to give the ClassLoadHelper a chance to initialize itself, |
||||
* including the oportunity to "steal" the class loader off of the calling |
||||
* thread, which is the thread that is initializing Quartz. |
||||
*/ |
||||
public void initialize() { |
||||
} |
||||
|
||||
/** |
||||
* Return the class with the given name. |
||||
*/ |
||||
public Class loadClass(String name) throws ClassNotFoundException { |
||||
return Class.forName(name); |
||||
} |
||||
|
||||
/** |
||||
* Finds a resource with a given name. This method returns null if no |
||||
* resource with this name is found. |
||||
* @param name name of the desired resource |
||||
* @return a java.net.URL object |
||||
*/ |
||||
public URL getResource(String name) { |
||||
return getClassLoader().getResource(name); |
||||
} |
||||
|
||||
/** |
||||
* Finds a resource with a given name. This method returns null if no |
||||
* resource with this name is found. |
||||
* @param name name of the desired resource |
||||
* @return a java.io.InputStream object |
||||
*/ |
||||
public InputStream getResourceAsStream(String name) { |
||||
return getClassLoader().getResourceAsStream(name); |
||||
} |
||||
|
||||
private ClassLoader getClassLoader() { |
||||
// To follow the same behavior of Class.forName(...) I had to play
|
||||
// dirty (Supported by Sun, IBM & BEA JVMs)
|
||||
// ToDo - Test it more.
|
||||
try { |
||||
// Get a reference to this class' class-loader
|
||||
ClassLoader cl = this.getClass().getClassLoader(); |
||||
// Create a method instance represnting the protected
|
||||
// getCallerClassLoader method of class ClassLoader
|
||||
Method mthd = ClassLoader.class.getDeclaredMethod( |
||||
"getCallerClassLoader", new Class[0]); |
||||
// Make the method accessible.
|
||||
AccessibleObject.setAccessible(new AccessibleObject[] {mthd}, true); |
||||
// Try to get the caller's class-loader
|
||||
return (ClassLoader)mthd.invoke(cl, new Object[0]); |
||||
} catch (Exception all) { |
||||
// Use this class' class-loader
|
||||
return this.getClass().getClassLoader(); |
||||
} |
||||
} |
||||
|
||||
} |
@ -1,89 +0,0 @@
|
||||
/* |
||||
* Copyright 2004-2005 OpenSymphony |
||||
* |
||||
* 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. |
||||
* |
||||
*/ |
||||
|
||||
/* |
||||
* Previously Copyright (c) 2001-2004 James House |
||||
*/ |
||||
package org.quartz.simpl; |
||||
|
||||
import org.quartz.spi.ClassLoadHelper; |
||||
|
||||
import java.net.URL; |
||||
import java.io.InputStream; |
||||
|
||||
/** |
||||
* A <code>ClassLoadHelper</code> that uses either the current thread's |
||||
* context class loader (<code>Thread.currentThread().getContextClassLoader().loadClass( .. )</code>). |
||||
* |
||||
* @see org.quartz.spi.ClassLoadHelper |
||||
* @see org.quartz.simpl.InitThreadContextClassLoadHelper |
||||
* @see org.quartz.simpl.SimpleClassLoadHelper |
||||
* @see org.quartz.simpl.CascadingClassLoadHelper |
||||
* @see org.quartz.simpl.LoadingLoaderClassLoadHelper |
||||
* |
||||
* @author jhouse |
||||
*/ |
||||
public class ThreadContextClassLoadHelper implements ClassLoadHelper { |
||||
|
||||
/* |
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
||||
* |
||||
* Interface. |
||||
* |
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
||||
*/ |
||||
|
||||
/** |
||||
* Called to give the ClassLoadHelper a chance to initialize itself, |
||||
* including the oportunity to "steal" the class loader off of the calling |
||||
* thread, which is the thread that is initializing Quartz. |
||||
*/ |
||||
public void initialize() { |
||||
} |
||||
|
||||
/** |
||||
* Return the class with the given name. |
||||
*/ |
||||
public Class loadClass(String name) throws ClassNotFoundException { |
||||
return getClassLoader().loadClass(name); |
||||
} |
||||
|
||||
/** |
||||
* Finds a resource with a given name. This method returns null if no |
||||
* resource with this name is found. |
||||
* @param name name of the desired resource |
||||
* @return a java.net.URL object |
||||
*/ |
||||
public URL getResource(String name) { |
||||
return getClassLoader().getResource(name); |
||||
} |
||||
|
||||
/** |
||||
* Finds a resource with a given name. This method returns null if no |
||||
* resource with this name is found. |
||||
* @param name name of the desired resource |
||||
* @return a java.io.InputStream object |
||||
*/ |
||||
public InputStream getResourceAsStream(String name) { |
||||
return getClassLoader().getResourceAsStream(name); |
||||
} |
||||
|
||||
|
||||
private ClassLoader getClassLoader() { |
||||
return Thread.currentThread().getContextClassLoader(); |
||||
} |
||||
} |
@ -1,69 +0,0 @@
|
||||
/* |
||||
* Copyright 2004-2005 OpenSymphony |
||||
* |
||||
* 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. |
||||
* |
||||
*/ |
||||
|
||||
/* |
||||
* Previously Copyright (c) 2001-2004 James House |
||||
*/ |
||||
package org.quartz.spi; |
||||
|
||||
import java.net.URL; |
||||
import java.io.InputStream; |
||||
|
||||
/** |
||||
* An interface for classes wishing to provide the service of loading classes |
||||
* and resources within the scheduler... |
||||
* |
||||
* @author jhouse |
||||
*/ |
||||
public interface ClassLoadHelper { |
||||
|
||||
/* |
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
||||
* |
||||
* Interface. |
||||
* |
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
||||
*/ |
||||
|
||||
/** |
||||
* Called to give the ClassLoadHelper a chance to initialize itself, |
||||
* including the oportunity to "steal" the class loader off of the calling |
||||
* thread, which is the thread that is initializing Quartz. |
||||
*/ |
||||
void initialize(); |
||||
|
||||
/** |
||||
* Return the class with the given name. |
||||
*/ |
||||
Class loadClass(String name) throws ClassNotFoundException; |
||||
|
||||
/** |
||||
* Finds a resource with a given name. This method returns null if no |
||||
* resource with this name is found. |
||||
* @param name name of the desired resource |
||||
* @return a java.net.URL object |
||||
*/ |
||||
URL getResource(String name); |
||||
|
||||
/** |
||||
* Finds a resource with a given name. This method returns null if no |
||||
* resource with this name is found. |
||||
* @param name name of the desired resource |
||||
* @return a java.io.InputStream object |
||||
*/ |
||||
InputStream getResourceAsStream(String name); |
||||
} |
Loading…
Reference in new issue