Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* ====================================================================
* Project: openMDX, http://www.openmdx.org/
* Description: Basic State Plug-In
* Owner: OMEX AG, Switzerland, http://www.omex.ch
* ====================================================================
*
* This software is published under the BSD license as listed below.
*
* Copyright (c) 2008-2012, OMEX AG, Switzerland
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of the openMDX team nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* ------------------
*
* This product includes software developed by other organizations as
* listed in the NOTICE file.
*/
package org.openmdx.state2.aop1;
import static org.openmdx.base.accessor.cci.SystemAttributes.CORE;
import static org.openmdx.base.accessor.cci.SystemAttributes.CREATED_AT;
import static org.openmdx.base.accessor.cci.SystemAttributes.REMOVED_AT;
import static org.openmdx.base.persistence.cci.Queries.ASPECT_QUERY;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.SortedMap;
import javax.jdo.JDOCanRetryException;
import javax.jdo.JDOUserException;
import javax.jdo.PersistenceManager;
import org.openmdx.base.accessor.cci.DataObject_1_0;
import org.openmdx.base.accessor.spi.ExceptionHelper;
import org.openmdx.base.accessor.view.Interceptor_1;
import org.openmdx.base.accessor.view.ObjectView_1_0;
import org.openmdx.base.aop1.Removable_1;
import org.openmdx.base.collection.Maps;
import org.openmdx.base.exception.RuntimeServiceException;
import org.openmdx.base.exception.ServiceException;
import org.openmdx.base.mof.cci.ModelElement_1_0;
import org.openmdx.base.mof.cci.ModelHelper;
import org.openmdx.base.mof.cci.Model_1_0;
import org.openmdx.base.mof.cci.Multiplicity;
import org.openmdx.kernel.exception.BasicException;
import org.openmdx.kernel.jdo.ReducedJDOHelper;
import org.openmdx.state2.cci.StateContext;
import org.openmdx.state2.cci.ViewKind;
import org.openmdx.state2.spi.Parameters;
import org.openmdx.state2.spi.Propagation;
import org.openmdx.state2.spi.StateViewContext;
import org.openmdx.state2.spi.TechnicalAttributes;
/**
* Basic State Plug-In
*/
public abstract class BasicState_1>
extends Removable_1
implements Involved
{
/**
* Constructor
*
* @param self the plug-in holder
* @param next the next plug-in
*
* @throws ServiceException
*/
protected BasicState_1(
ObjectView_1_0 self,
Interceptor_1 next
) throws ServiceException{
super(self, next);
DataObject_1_0 delegate = self.objGetDelegate();
this.views = Maps.newMap(isMultithreaded());
this.enabled = !getModel().isInstanceof(delegate, "org:openmdx:state2:BasicState");
if (!this.enabled && !delegate.jdoIsPersistent() && !delegate.jdoIsTransactional()) {
initialize(delegate);
}
}
/**
* View Cache
*/
private final Map views;
/**
* true for state views.
*/
private boolean enabled = false;
/**
*
*/
private transient Map,?> coreFeatures;
/**
* Lazily initalized for TIME_POINT access mode FOR_QUERY
*/
private transient Iterable forTimePointQuery;
/**
* Lazily initalized for TIME_RANGE access mode FOR_QUERY
*/
private transient Iterable forTimeRangeQuery;
/**
* Lazily initalized for TIME_RANGE access mode UNDERLYING_STATE
*/
private transient Iterable forUnderlyingState;
/**
* Lazily initalized for TIME_RANGE access mode FOR_UPDATE
*/
private transient Iterable forUpdate;
/**
* Tells whether this instances handles a state view, a transient state or an object
* with unique valid time.
*
* @param feature the feature to be tested
*
* @return true for state view features
*
* @throws ServiceException
*/
private boolean isViewFeature(
String feature
) throws ServiceException {
if(this.enabled) {
if(this.coreFeatures == null) {
this.coreFeatures = getModel().getElement(
this.self.objGetDelegate().objGetClass()
).objGetMap("allFeature");
}
return !this.coreFeatures.containsKey(feature);
} else {
return false;
}
}
/**
* Tests whether a given state is involved in the given context
*
* @param candidate
* @param context
* @param accessMode
* @return true if the candidate is involved
*
* @throws ServiceException
*/
protected boolean isInvolved(
DataObject_1_0 candidate,
C context,
AccessMode accessMode
) throws ServiceException {
if(!candidate.jdoIsDeleted() && getModel().isInstanceof(candidate, "org:openmdx:state2:BasicState")) {
final Date removedAt = (Date) candidate.objGetValue(REMOVED_AT);
switch(context.getViewKind()) {
case TIME_POINT_VIEW:
if(context.getExistsAt() == null) {
return removedAt == null;
} else {
final Date createdAt = (Date)candidate.objGetValue(CREATED_AT);
return
candidate.jdoIsPersistent() &&
!candidate.jdoIsNew() &&
StateViewContext.compareTransactionTime(
context.getExistsAt(),
createdAt,
removedAt
);
}
case TIME_RANGE_VIEW:
return removedAt == null;
default:
throw new RuntimeServiceException(
BasicException.Code.DEFAULT_DOMAIN,
BasicException.Code.ASSERTION_FAILURE,
"Unexpected view kind",
new BasicException.Parameter("context",context)
);
}
} else {
return false;
}
}
protected abstract void initialize(
DataObject_1_0 dataObject
) throws ServiceException;
protected abstract boolean isValidTimeFeature(
String featureName
);
/**
* Clone or split state
*
* @param source
* @throws ServiceException
*/
protected abstract void enableUpdate(
Map source
) throws ServiceException;
/**
* Tells whether the state starts before the time range's start point or
* ends after the time range's end point.
*
* @param state
*
* @return true if the state crosses at least one of the
* time range limits.
*/
protected abstract BoundaryCrossing getBoundaryCrossing(
DataObject_1_0 state
) throws ServiceException;
@SuppressWarnings("unchecked")
protected Collection getStates(
DataObject_1_0 core
){
return (Collection) core.jdoGetPersistenceManager().newNamedQuery(
null,
ASPECT_QUERY
).execute(
"org:openmdx:state2:BasicState",
core
);
}
/* (non-Javadoc)
* @see org.openmdx.state2.aop2.core.AbstractState_1#getStates()
*/
protected Collection getStates(
) throws ServiceException {
return getStates(self.objGetDelegate());
}
protected boolean isActive(
DataObject_1_0 state
) throws ServiceException{
return
!state.jdoIsDeleted() &&
state.objGetValue(REMOVED_AT) == null;
}
protected boolean isNew(
DataObject_1_0 state
) throws ServiceException{
return
!state.jdoIsDeleted() &&
state.jdoIsNew();
}
/**
* Tells whether the state is to be removed when this unit of work completes
*
* @param state the state to be inspected
* @return {@code true} if the state is to be removed when this unit of work completes
*
* @throws ServiceException if retrieving the {@code REMOVED_AT} value fails
*/
protected boolean isToBeRemoved(
DataObject_1_0 state
) throws ServiceException{
return
!state.jdoIsDeleted() &&
IN_THE_FUTURE.equals(state.objGetValue(REMOVED_AT));
}
protected abstract boolean interfersWith(
DataObject_1_0 state
) throws ServiceException;
/**
* Retrieve the view's context
*
* @return the view's context
*/
@SuppressWarnings("unchecked")
protected final C getContext(
){
return (C) this.self.getInteractionSpec();
}
/* (non-Javadoc)
* @see org.openmdx.state2.aop1.Involved#getQueryAccessMode()
*/
@Override
public AccessMode getQueryAccessMode() {
return Parameters.STRICT_QUERY && getContext().getViewKind() == ViewKind.TIME_RANGE_VIEW ?
AccessMode.UNDERLYING_STATE :
AccessMode.FOR_QUERY;
}
/* (non-Javadoc)
* @see org.openmdx.state2.plugin.Involved#getInvolved(org.openmdx.state2.plugin.AccessMode)
*/
public Iterable getInvolved(
final AccessMode accessMode
){
ViewKind viewKind = getContext().getViewKind();
switch(viewKind) {
case TIME_RANGE_VIEW:
switch(accessMode) {
case FOR_QUERY:
if(this.forTimeRangeQuery == null) {
this.forTimeRangeQuery = new MultiStateCache(accessMode);
}
return this.forTimeRangeQuery;
case UNDERLYING_STATE:
if(this.forUnderlyingState == null) {
this.forUnderlyingState = new SingleStateCache(accessMode);
}
return this.forUnderlyingState;
case FOR_UPDATE:
if(this.forUpdate == null) {
this.forUpdate = new InvolvedStatesForUpdate();
}
return this.forUpdate;
}
case TIME_POINT_VIEW:
switch(accessMode) {
case FOR_QUERY:
if(this.forTimePointQuery == null) {
this.forTimePointQuery = new SingleStateCache(accessMode);
}
return this.forTimePointQuery;
default:
// fall through to exception
break;
}
}
throw new RuntimeServiceException(
BasicException.Code.DEFAULT_DOMAIN,
BasicException.Code.BAD_PARAMETER,
"Illegal access mode for the given view kind",
getIdParameter(),
new BasicException.Parameter("viewKind", viewKind),
ExceptionHelper.newObjectIdParameter("accessMode", accessMode)
);
}
/* (non-Javadoc)
* @see org.openmdx.base.accessor.generic.spi.StaticallyDelegatingObject_1#objGetList(java.lang.String)
*/
@SuppressWarnings("unchecked")
@Override
public List