You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by nt...@apache.org on 2017/12/12 13:05:45 UTC
[3/5] cayenne git commit: CAY-2373 cayenne-rop-server module - move
org.apache.cayenne.remote package to cayenne-rop server module - remove
dependencies from cayenne-server pom.xml - update tutorial
http://git-wip-us.apache.org/repos/asf/cayenne/blob/38f37d79/cayenne-rop-server/src/test/java/org/apache/cayenne/remote/service/BaseRemoteServiceTest.java
----------------------------------------------------------------------
diff --git a/cayenne-rop-server/src/test/java/org/apache/cayenne/remote/service/BaseRemoteServiceTest.java b/cayenne-rop-server/src/test/java/org/apache/cayenne/remote/service/BaseRemoteServiceTest.java
new file mode 100644
index 0000000..00feca6
--- /dev/null
+++ b/cayenne-rop-server/src/test/java/org/apache/cayenne/remote/service/BaseRemoteServiceTest.java
@@ -0,0 +1,142 @@
+/*****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ****************************************************************/
+package org.apache.cayenne.remote.service;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.fail;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.cayenne.CayenneRuntimeException;
+import org.apache.cayenne.DataChannel;
+import org.apache.cayenne.ObjectContext;
+import org.apache.cayenne.configuration.Constants;
+import org.apache.cayenne.configuration.ObjectContextFactory;
+import org.apache.cayenne.event.MockEventBridgeFactory;
+import org.apache.cayenne.query.Query;
+import org.apache.cayenne.remote.QueryMessage;
+import org.apache.cayenne.remote.RemoteSession;
+import org.apache.cayenne.util.Util;
+import org.junit.Test;
+
+public class BaseRemoteServiceTest {
+
+ @Test
+ public void testConstructor() throws Exception {
+
+ Map<String, String> map = new HashMap<>();
+ map.put(Constants.SERVER_ROP_EVENT_BRIDGE_FACTORY_PROPERTY, MockEventBridgeFactory.class.getName());
+
+ ObjectContextFactory factory = new ObjectContextFactory() {
+
+ public ObjectContext createContext(DataChannel parent) {
+ return null;
+ }
+
+ public ObjectContext createContext() {
+ return null;
+ }
+ };
+ BaseRemoteService service = new BaseRemoteService(factory, map) {
+
+ @Override
+ protected ServerSession createServerSession() {
+ return null;
+ }
+
+ @Override
+ protected ServerSession createServerSession(String name) {
+ return null;
+ }
+
+ @Override
+ protected ServerSession getServerSession() {
+ return null;
+ }
+ };
+ assertEquals(MockEventBridgeFactory.class.getName(), service.getEventBridgeFactoryName());
+ assertSame(factory, service.contextFactory);
+
+ }
+
+ @Test
+ public void testProcessMessageExceptionSerializability() throws Throwable {
+
+ Map<String, String> map = new HashMap<>();
+ ObjectContextFactory factory = new ObjectContextFactory() {
+
+ public ObjectContext createContext(DataChannel parent) {
+ return null;
+ }
+
+ public ObjectContext createContext() {
+ return null;
+ }
+ };
+ BaseRemoteService service = new BaseRemoteService(factory, map) {
+
+ @Override
+ protected ServerSession createServerSession() {
+ return new ServerSession(new RemoteSession("a"), null);
+ }
+
+ @Override
+ protected ServerSession createServerSession(String name) {
+ return createServerSession();
+ }
+
+ @Override
+ protected ServerSession getServerSession() {
+ return createServerSession();
+ }
+ };
+
+ try {
+ service.processMessage(new QueryMessage(null) {
+
+ @Override
+ public Query getQuery() {
+ // serializable exception thrown
+ throw new CayenneRuntimeException();
+ }
+ });
+
+ fail("Expected to throw");
+ } catch (Exception ex) {
+ Util.cloneViaSerialization(ex);
+ }
+
+ try {
+ service.processMessage(new QueryMessage(null) {
+
+ @Override
+ public Query getQuery() {
+ // non-serializable exception thrown
+ throw new MockUnserializableException();
+ }
+ });
+
+ fail("Expected to throw");
+ } catch (Exception ex) {
+ Util.cloneViaSerialization(ex);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/38f37d79/cayenne-rop-server/src/test/java/org/apache/cayenne/remote/service/DispatchHelperTest.java
----------------------------------------------------------------------
diff --git a/cayenne-rop-server/src/test/java/org/apache/cayenne/remote/service/DispatchHelperTest.java b/cayenne-rop-server/src/test/java/org/apache/cayenne/remote/service/DispatchHelperTest.java
new file mode 100644
index 0000000..e4b01fe
--- /dev/null
+++ b/cayenne-rop-server/src/test/java/org/apache/cayenne/remote/service/DispatchHelperTest.java
@@ -0,0 +1,54 @@
+/*****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ****************************************************************/
+
+package org.apache.cayenne.remote.service;
+
+import org.apache.cayenne.CayenneRuntimeException;
+import org.apache.cayenne.MockDataChannel;
+import org.apache.cayenne.map.EntityResolver;
+import org.apache.cayenne.remote.BootstrapMessage;
+import org.apache.cayenne.remote.ClientMessage;
+import org.junit.Test;
+
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.mock;
+
+public class DispatchHelperTest {
+
+ @Test
+ public void testBootstrapMessage() {
+ EntityResolver resolver = new EntityResolver();
+ MockDataChannel channel = new MockDataChannel(resolver);
+ assertSame(resolver.getClientEntityResolver(), DispatchHelper.dispatch(
+ channel,
+ new BootstrapMessage()));
+ }
+
+ @Test
+ public void testUnknownMessage() {
+ try {
+ DispatchHelper.dispatch(new MockDataChannel(), mock(ClientMessage.class));
+ fail("Unknown message must have failed");
+ }
+ catch (CayenneRuntimeException e) {
+ // expected
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/38f37d79/cayenne-rop-server/src/test/java/org/apache/cayenne/remote/service/MockUnserializableException.java
----------------------------------------------------------------------
diff --git a/cayenne-rop-server/src/test/java/org/apache/cayenne/remote/service/MockUnserializableException.java b/cayenne-rop-server/src/test/java/org/apache/cayenne/remote/service/MockUnserializableException.java
new file mode 100644
index 0000000..e30435b
--- /dev/null
+++ b/cayenne-rop-server/src/test/java/org/apache/cayenne/remote/service/MockUnserializableException.java
@@ -0,0 +1,24 @@
+/*****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ****************************************************************/
+package org.apache.cayenne.remote.service;
+
+class MockUnserializableException extends RuntimeException {
+
+ protected Object notSerializableField = new Object();
+}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/38f37d79/cayenne-server/pom.xml
----------------------------------------------------------------------
diff --git a/cayenne-server/pom.xml b/cayenne-server/pom.xml
index 4b7fb6b..a310a37 100644
--- a/cayenne-server/pom.xml
+++ b/cayenne-server/pom.xml
@@ -32,7 +32,6 @@
<dependencies>
<!-- Compile dependencies -->
-
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
@@ -44,31 +43,6 @@
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
- <!-- Optional dependencies... things that might have been placed in submodules... -->
- <dependency>
- <groupId>com.caucho</groupId>
- <artifactId>hessian</artifactId>
- <scope>provided</scope>
- <optional>true</optional>
- </dependency>
- <dependency>
- <groupId>opensymphony</groupId>
- <artifactId>oscache</artifactId>
- <scope>provided</scope>
- <optional>true</optional>
- </dependency>
- <dependency>
- <groupId>net.sf.ehcache</groupId>
- <artifactId>ehcache-core</artifactId>
- <scope>provided</scope>
- <optional>true</optional>
- </dependency>
- <dependency>
- <groupId>javax.servlet</groupId>
- <artifactId>servlet-api</artifactId>
- <scope>provided</scope>
- <optional>true</optional>
- </dependency>
<!-- Test dependencies -->
<dependency>
@@ -110,11 +84,6 @@
</exclusions>
</dependency>
<dependency>
- <groupId>com.mockrunner</groupId>
- <artifactId>mockrunner-servlet</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<scope>test</scope>
http://git-wip-us.apache.org/repos/asf/cayenne/blob/38f37d79/cayenne-server/src/main/java/org/apache/cayenne/CayenneContext.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/CayenneContext.java b/cayenne-server/src/main/java/org/apache/cayenne/CayenneContext.java
deleted file mode 100644
index c352ae0..0000000
--- a/cayenne-server/src/main/java/org/apache/cayenne/CayenneContext.java
+++ /dev/null
@@ -1,391 +0,0 @@
-/*****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- ****************************************************************/
-
-package org.apache.cayenne;
-
-import org.apache.cayenne.event.EventManager;
-import org.apache.cayenne.graph.CompoundDiff;
-import org.apache.cayenne.graph.GraphDiff;
-import org.apache.cayenne.graph.GraphManager;
-import org.apache.cayenne.map.ObjEntity;
-import org.apache.cayenne.query.Query;
-import org.apache.cayenne.reflect.ClassDescriptor;
-import org.apache.cayenne.util.EventUtil;
-import org.apache.cayenne.validation.ValidationException;
-import org.apache.cayenne.validation.ValidationResult;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * A default generic implementation of ObjectContext suitable for accessing
- * Cayenne from either an ORM or a client tiers. Communicates with Cayenne via a
- * {@link org.apache.cayenne.DataChannel}.
- *
- * @since 1.2
- */
-public class CayenneContext extends BaseContext {
-
- CayenneContextGraphManager graphManager;
-
- // object that merges "backdoor" changes that come from the channel.
- CayenneContextMergeHandler mergeHandler;
-
- /**
- * Creates a new CayenneContext with no channel and disabled graph events.
- */
- public CayenneContext() {
- this(null);
- }
-
- /**
- * Creates a new CayenneContext, initializing it with a channel instance.
- * CayenneContext created using this constructor WILL NOT broadcast graph
- * change events.
- */
- public CayenneContext(DataChannel channel) {
- this(channel, false, false);
- }
-
- /**
- * Creates a new CayenneContext, initializing it with a channel.
- */
- public CayenneContext(DataChannel channel, boolean changeEventsEnabled, boolean lifecyleEventsEnabled) {
-
- graphManager = new CayenneContextGraphManager(this, changeEventsEnabled, lifecyleEventsEnabled);
-
- if (channel != null) {
- attachToChannel(channel);
- }
- }
-
- /**
- * @since 3.1
- */
- @Override
- protected void attachToChannel(DataChannel channel) {
- super.attachToChannel(channel);
-
- if (mergeHandler != null) {
- mergeHandler.active = false;
- mergeHandler = null;
- }
-
- EventManager eventManager = channel.getEventManager();
- if (eventManager != null) {
- mergeHandler = new CayenneContextMergeHandler(this);
-
- // listen to our channel events...
- // note that we must reset listener on channel switch, as there is
- // no
- // guarantee that a new channel uses the same EventManager.
- EventUtil.listenForChannelEvents(channel, mergeHandler);
- }
- }
-
- /**
- * Returns true if this context posts individual object modification events.
- * Subject used for these events is
- * <code>ObjectContext.GRAPH_CHANGED_SUBJECT</code>.
- */
- public boolean isChangeEventsEnabled() {
- return graphManager.changeEventsEnabled;
- }
-
- /**
- * Returns true if this context posts lifecycle events. Subjects used for
- * these events are
- * <code>ObjectContext.GRAPH_COMMIT_STARTED_SUBJECT, ObjectContext.GRAPH_COMMITTED_SUBJECT,
- * ObjectContext.GRAPH_COMMIT_ABORTED_SUBJECT, ObjectContext.GRAPH_ROLLEDBACK_SUBJECT.</code>
- * .
- */
- public boolean isLifecycleEventsEnabled() {
- return graphManager.lifecycleEventsEnabled;
- }
-
- @Override
- public GraphManager getGraphManager() {
- return graphManager;
- }
-
- CayenneContextGraphManager internalGraphManager() {
- return graphManager;
- }
-
- /**
- * Commits changes to uncommitted objects. First checks if there are changes
- * in this context and if any changes are detected, sends a commit message
- * to remote Cayenne service via an internal instance of CayenneConnector.
- */
- @Override
- public void commitChanges() {
- doCommitChanges(true);
- }
-
- GraphDiff doCommitChanges(boolean cascade) {
-
- int syncType = cascade ? DataChannel.FLUSH_CASCADE_SYNC : DataChannel.FLUSH_NOCASCADE_SYNC;
-
- GraphDiff commitDiff = null;
-
- synchronized (graphManager) {
-
- if (graphManager.hasChanges()) {
-
- if (isValidatingObjectsOnCommit()) {
- ValidationResult result = new ValidationResult();
- Iterator<?> it = graphManager.dirtyNodes().iterator();
- while (it.hasNext()) {
- Persistent p = (Persistent) it.next();
- if (p instanceof Validating) {
- switch (p.getPersistenceState()) {
- case PersistenceState.NEW:
- ((Validating) p).validateForInsert(result);
- break;
- case PersistenceState.MODIFIED:
- ((Validating) p).validateForUpdate(result);
- break;
- case PersistenceState.DELETED:
- ((Validating) p).validateForDelete(result);
- break;
- }
- }
- }
-
- if (result.hasFailures()) {
- throw new ValidationException(result);
- }
- }
-
- graphManager.graphCommitStarted();
-
- GraphDiff changes = graphManager.getDiffsSinceLastFlush();
-
- try {
- commitDiff = channel.onSync(this, changes, syncType);
- } catch (Throwable th) {
- graphManager.graphCommitAborted();
-
- if (th instanceof CayenneRuntimeException) {
- throw (CayenneRuntimeException) th;
- } else {
- throw new CayenneRuntimeException("Commit error", th);
- }
- }
-
- graphManager.graphCommitted(commitDiff);
-
- // this event is caught by peer nested ObjectContexts to
- // synchronize the
- // state
- fireDataChannelCommitted(this, changes);
- }
- }
-
- return commitDiff;
- }
-
- @Override
- public void commitChangesToParent() {
- doCommitChanges(false);
- }
-
- @Override
- public void rollbackChanges() {
- synchronized (graphManager) {
- if (graphManager.hasChanges()) {
-
- GraphDiff diff = graphManager.getDiffs();
- graphManager.graphReverted();
-
- channel.onSync(this, diff, DataChannel.ROLLBACK_CASCADE_SYNC);
- fireDataChannelRolledback(this, diff);
- }
- }
- }
-
- @Override
- public void rollbackChangesLocally() {
- synchronized (graphManager) {
- if (graphManager.hasChanges()) {
- GraphDiff diff = graphManager.getDiffs();
- graphManager.graphReverted();
-
- fireDataChannelRolledback(this, diff);
- }
- }
- }
-
- /**
- * Creates and registers a new Persistent object instance.
- */
- @Override
- public <T> T newObject(Class<T> persistentClass) {
- if (persistentClass == null) {
- throw new NullPointerException("Persistent class can't be null.");
- }
-
- ObjEntity entity = getEntityResolver().getObjEntity(persistentClass);
- if (entity == null) {
- throw new CayenneRuntimeException("No entity mapped for class: %s", persistentClass);
- }
-
- ClassDescriptor descriptor = getEntityResolver().getClassDescriptor(entity.getName());
- @SuppressWarnings("unchecked")
- T object = (T) descriptor.createObject();
- descriptor.injectValueHolders(object);
- registerNewObject((Persistent) object, entity.getName(), descriptor);
- return object;
- }
-
- /**
- * @since 3.0
- */
- @Override
- public void registerNewObject(Object object) {
- if (object == null) {
- throw new NullPointerException("An attempt to register null object.");
- }
-
- ObjEntity entity = getEntityResolver().getObjEntity(object.getClass());
- ClassDescriptor descriptor = getEntityResolver().getClassDescriptor(entity.getName());
- registerNewObject((Persistent) object, entity.getName(), descriptor);
- }
-
- /**
- * Runs a query, returning result as list.
- */
- @Override
- public List performQuery(Query query) {
- List result = onQuery(this, query).firstList();
- return result != null ? result : new ArrayList<>(1);
- }
-
- @Override
- public QueryResponse performGenericQuery(Query query) {
- return onQuery(this, query);
- }
-
- public QueryResponse onQuery(ObjectContext context, Query query) {
- return new CayenneContextQueryAction(this, context, query).execute();
- }
-
- @Override
- public Collection<?> uncommittedObjects() {
- synchronized (graphManager) {
- return graphManager.dirtyNodes();
- }
- }
-
- @Override
- public Collection<?> deletedObjects() {
- synchronized (graphManager) {
- return graphManager.dirtyNodes(PersistenceState.DELETED);
- }
- }
-
- @Override
- public Collection<?> modifiedObjects() {
- synchronized (graphManager) {
- return graphManager.dirtyNodes(PersistenceState.MODIFIED);
- }
- }
-
- @Override
- public Collection<?> newObjects() {
- synchronized (graphManager) {
- return graphManager.dirtyNodes(PersistenceState.NEW);
- }
- }
-
- // ****** non-public methods ******
-
- void registerNewObject(Persistent object, String entityName, ClassDescriptor descriptor) {
- /**
- * We should create new id only if it is not set for this object. It
- * could have been created, for instance, in child context
- */
- ObjectId id = object.getObjectId();
- if (id == null) {
- id = new ObjectId(entityName);
- object.setObjectId(id);
- }
-
- injectInitialValue(object);
- }
-
- Persistent createFault(ObjectId id) {
- ClassDescriptor descriptor = getEntityResolver().getClassDescriptor(id.getEntityName());
-
- Persistent object = (Persistent) descriptor.createObject();
-
- object.setPersistenceState(PersistenceState.HOLLOW);
- object.setObjectContext(this);
- object.setObjectId(id);
-
- graphManager.registerNode(id, object);
-
- return object;
- }
-
- @Override
- protected GraphDiff onContextFlush(ObjectContext originatingContext, GraphDiff changes, boolean cascade) {
-
- boolean childContext = this != originatingContext && changes != null;
-
- if (childContext) {
-
- // PropertyChangeProcessingStrategy oldStrategy =
- // getPropertyChangeProcessingStrategy();
- // setPropertyChangeProcessingStrategy(PropertyChangeProcessingStrategy.RECORD);
- try {
- changes.apply(new CayenneContextChildDiffLoader(this));
- } finally {
- // setPropertyChangeProcessingStrategy(oldStrategy);
- }
-
- fireDataChannelChanged(originatingContext, changes);
- }
-
- return (cascade) ? doCommitChanges(true) : new CompoundDiff();
- }
-
- /**
- * Returns <code>true</code> if there are any modified, deleted or new
- * objects registered with this CayenneContext, <code>false</code>
- * otherwise.
- */
- public boolean hasChanges() {
- return graphManager.hasChanges();
- }
-
- /**
- * This method simply returns an iterator over a list of selected objects.
- * There's no performance benefit of using it vs. regular "select".
- *
- * @since 4.0
- */
- public <T> ResultIterator<T> iterator(org.apache.cayenne.query.Select<T> query) {
- List<T> objects = select(query);
- return new CollectionResultIterator<T>(objects);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/38f37d79/cayenne-server/src/main/java/org/apache/cayenne/CayenneContextChildDiffLoader.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/CayenneContextChildDiffLoader.java b/cayenne-server/src/main/java/org/apache/cayenne/CayenneContextChildDiffLoader.java
deleted file mode 100644
index 151b72e..0000000
--- a/cayenne-server/src/main/java/org/apache/cayenne/CayenneContextChildDiffLoader.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- ****************************************************************/
-package org.apache.cayenne;
-
-import org.apache.cayenne.graph.ChildDiffLoader;
-import org.apache.cayenne.reflect.ArcProperty;
-import org.apache.cayenne.reflect.AttributeProperty;
-import org.apache.cayenne.reflect.ClassDescriptor;
-import org.apache.cayenne.reflect.PropertyDescriptor;
-import org.apache.cayenne.reflect.PropertyVisitor;
-import org.apache.cayenne.reflect.ToManyProperty;
-import org.apache.cayenne.reflect.ToOneProperty;
-
-/**
- * Used for loading child's CayenneContext changes to parent context.
- *
- * @since 3.0
- */
-class CayenneContextChildDiffLoader extends ChildDiffLoader {
-
- public CayenneContextChildDiffLoader(CayenneContext context) {
- super(context);
- }
-
- @Override
- public void nodePropertyChanged(
- Object nodeId,
- String property,
- Object oldValue,
- Object newValue) {
-
- super.nodePropertyChanged(nodeId, property, oldValue, newValue);
-
- Persistent object = (Persistent) context.getGraphManager().getNode(nodeId);
- context.propertyChanged(object, property, oldValue, newValue);
- }
-
- @Override
- public void arcCreated(Object nodeId, Object targetNodeId, Object arcId) {
-
- final Persistent source = findObject(nodeId);
- final Persistent target = findObject(targetNodeId);
-
- // if a target was later deleted, the diff for arcCreated is still preserved and
- // can result in NULL target here.
- if (target == null) {
- return;
- }
-
- ClassDescriptor descriptor = context.getEntityResolver().getClassDescriptor(
- ((ObjectId) nodeId).getEntityName());
- ArcProperty property = (ArcProperty) descriptor.getProperty(arcId.toString());
-
- property.visit(new PropertyVisitor() {
-
- public boolean visitAttribute(AttributeProperty property) {
- return false;
- }
-
- public boolean visitToMany(ToManyProperty property) {
- property.addTargetDirectly(source, target);
- return false;
- }
-
- public boolean visitToOne(ToOneProperty property) {
- property.setTarget(source, target, false);
- return false;
- }
- });
- context.propertyChanged(source, (String) arcId, null, target);
- }
-
- @Override
- public void arcDeleted(Object nodeId, final Object targetNodeId, Object arcId) {
- final Persistent source = findObject(nodeId);
-
- // needed as sometime temporary objects are evoked from the context before
- // changing their relationships
- if (source == null) {
- return;
- }
-
- ClassDescriptor descriptor = context.getEntityResolver().getClassDescriptor(
- ((ObjectId) nodeId).getEntityName());
- PropertyDescriptor property = descriptor.getProperty(arcId.toString());
-
- final Persistent[] target = new Persistent[1];
- target[0] = findObject(targetNodeId);
-
- property.visit(new PropertyVisitor() {
-
- public boolean visitAttribute(AttributeProperty property) {
- return false;
- }
-
- public boolean visitToMany(ToManyProperty property) {
- if (target[0] == null) {
-
- // this is usually the case when a NEW object was deleted and then
- // its relationships were manipulated; so try to locate the object
- // in the collection ... the performance of this is rather dubious
- // of course...
- target[0] = findObjectInCollection(targetNodeId, property
- .readProperty(source));
- }
-
- if (target[0] == null) {
- // ignore?
- }
- else {
- property.removeTargetDirectly(source, target[0]);
- }
-
- return false;
- }
-
- public boolean visitToOne(ToOneProperty property) {
- property.setTarget(source, null, false);
- return false;
- }
- });
-
- context.propertyChanged(source, (String) arcId, target[0], null);
- }
-
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cayenne/blob/38f37d79/cayenne-server/src/main/java/org/apache/cayenne/CayenneContextGraphManager.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/CayenneContextGraphManager.java b/cayenne-server/src/main/java/org/apache/cayenne/CayenneContextGraphManager.java
deleted file mode 100644
index f4865c0..0000000
--- a/cayenne-server/src/main/java/org/apache/cayenne/CayenneContextGraphManager.java
+++ /dev/null
@@ -1,379 +0,0 @@
-/*****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- ****************************************************************/
-
-package org.apache.cayenne;
-
-import org.apache.cayenne.event.EventManager;
-import org.apache.cayenne.event.EventSubject;
-import org.apache.cayenne.graph.ArcCreateOperation;
-import org.apache.cayenne.graph.ArcDeleteOperation;
-import org.apache.cayenne.graph.GraphChangeHandler;
-import org.apache.cayenne.graph.GraphDiff;
-import org.apache.cayenne.graph.GraphEvent;
-import org.apache.cayenne.graph.GraphMap;
-import org.apache.cayenne.graph.NodeCreateOperation;
-import org.apache.cayenne.graph.NodeDeleteOperation;
-import org.apache.cayenne.graph.NodeIdChangeOperation;
-import org.apache.cayenne.graph.NodePropertyChangeOperation;
-import org.apache.cayenne.map.EntityResolver;
-import org.apache.cayenne.reflect.ArcProperty;
-import org.apache.cayenne.reflect.ClassDescriptor;
-import org.apache.cayenne.reflect.PropertyException;
-import org.apache.cayenne.reflect.ToManyMapProperty;
-import org.apache.cayenne.util.PersistentObjectMap;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.Map;
-
-/**
- * A GraphMap extension that works together with {@link ObjectContext} to track persistent object
- * changes and send events.
- *
- * @since 1.2
- */
-final class CayenneContextGraphManager extends GraphMap {
-
- static final String COMMIT_MARKER = "commit";
- static final String FLUSH_MARKER = "flush";
-
- CayenneContext context;
- Collection<Object> deadIds;
- boolean changeEventsEnabled;
- boolean lifecycleEventsEnabled;
-
- ObjectContextStateLog stateLog;
- ObjectContextChangeLog changeLog;
-
- CayenneContextGraphManager(CayenneContext context, boolean changeEventsEnabled,
- boolean lifecycleEventsEnabled) {
-
- this.context = context;
- this.changeEventsEnabled = changeEventsEnabled;
- this.lifecycleEventsEnabled = lifecycleEventsEnabled;
-
- this.stateLog = new ObjectContextStateLog(this);
- this.changeLog = new ObjectContextChangeLog();
- }
-
- boolean hasChanges() {
- return changeLog.size() > 0;
- }
-
- boolean hasChangesSinceLastFlush() {
- int size = changeLog.hasMarker(FLUSH_MARKER) ? changeLog
- .sizeAfterMarker(FLUSH_MARKER) : changeLog.size();
- return size > 0;
- }
-
- GraphDiff getDiffs() {
- return changeLog.getDiffs();
- }
-
- GraphDiff getDiffsSinceLastFlush() {
- return changeLog.hasMarker(FLUSH_MARKER) ? changeLog
- .getDiffsAfterMarker(FLUSH_MARKER) : changeLog.getDiffs();
- }
-
- Collection<Object> dirtyNodes() {
- return stateLog.dirtyNodes();
- }
-
- Collection<Object> dirtyNodes(int state) {
- return stateLog.dirtyNodes(state);
- }
-
- @Override
- public synchronized Object unregisterNode(Object nodeId) {
- Object node = super.unregisterNode(nodeId);
-
- // remove node from other collections...
- if (node != null) {
- stateLog.unregisterNode(nodeId);
- changeLog.unregisterNode(nodeId);
- Persistent object = (Persistent)node;
- object.setObjectContext(null);
- object.setPersistenceState(PersistenceState.TRANSIENT);
- return node;
- }
-
- return null;
- }
-
- // ****** Sync Events API *****
- /**
- * Clears commit marker, but keeps all recorded operations.
- */
- void graphCommitAborted() {
- changeLog.removeMarker(COMMIT_MARKER);
- }
-
- /**
- * Sets commit start marker in the change log. If events are enabled, posts commit
- * start event.
- */
- void graphCommitStarted() {
- changeLog.setMarker(COMMIT_MARKER);
- }
-
- void graphCommitted(GraphDiff parentSyncDiff) {
- if (parentSyncDiff != null) {
- new CayenneContextMergeHandler(context).merge(parentSyncDiff);
- }
-
- remapTargets();
-
- stateLog.graphCommitted();
- reset();
-
- if (lifecycleEventsEnabled) {
- // include all diffs after the commit start marker.
- // We fire event as if it was posted by parent channel, so that
- // nested contexts could catch it
- context.fireDataChannelCommitted(context.getChannel(), parentSyncDiff);
- }
- }
-
- /**
- * Remaps keys in to-many map relationships that contain dirty objects with
- * potentially modified properties.
- */
- private void remapTargets() {
-
- Iterator<Object> it = stateLog.dirtyIds().iterator();
-
- EntityResolver resolver = context.getEntityResolver();
-
- while (it.hasNext()) {
- ObjectId id = (ObjectId) it.next();
- ClassDescriptor descriptor = resolver.getClassDescriptor(id.getEntityName());
-
- Collection<ArcProperty> mapArcProperties = descriptor.getMapArcProperties();
- if (!mapArcProperties.isEmpty()) {
-
- Object object = getNode(id);
-
- for (ArcProperty arc : mapArcProperties) {
- ToManyMapProperty reverseArc = (ToManyMapProperty) arc
- .getComplimentaryReverseArc();
-
- Object source = arc.readPropertyDirectly(object);
- if (source != null && !reverseArc.isFault(source)) {
- remapTarget(reverseArc, source, object);
- }
- }
- }
- }
- }
-
- // clone of DataDomainSyncBucket.remapTarget
- private final void remapTarget(
- ToManyMapProperty property,
- Object source,
- Object target) throws PropertyException {
-
- @SuppressWarnings("unchecked")
- Map<Object, Object> map = (Map<Object, Object>) property.readProperty(source);
-
- Object newKey = property.getMapKey(target);
- Object currentValue = map.get(newKey);
-
- if (currentValue == target) {
- // nothing to do
- return;
- }
- // else - do not check for conflicts here (i.e. another object mapped for the same
- // key), as we have no control of the order in which this method is called, so
- // another object may be remapped later by the caller
-
- // must do a slow map scan to ensure the object is not mapped under a different
- // key...
- Iterator<?> it = map.entrySet().iterator();
- while (it.hasNext()) {
- Map.Entry<?, ?> e = (Map.Entry<?, ?>) it.next();
- if (e.getValue() == target) {
- // this remove does not trigger event in PersistentObjectMap
- it.remove();
- break;
- }
- }
-
- // TODO: (andrey, 25/11/09 - this is a hack to prevent event triggering
- // (and concurrent exceptions)
- // should find a way to get rid of type casting
- ((PersistentObjectMap) map).putDirectly(newKey, target);
- }
-
- void graphFlushed() {
- changeLog.setMarker(FLUSH_MARKER);
- }
-
- void graphReverted() {
- GraphDiff diff = changeLog.getDiffs();
-
- diff.undo(new RollbackChangeHandler());
- stateLog.graphReverted();
- reset();
-
- if (lifecycleEventsEnabled) {
- context.fireDataChannelRolledback(context, diff);
- }
- }
-
- // ****** GraphChangeHandler API ******
- // =====================================================
-
- @Override
- public synchronized void nodeIdChanged(Object nodeId, Object newId) {
- stateLog.nodeIdChanged(nodeId, newId);
- processChange(new NodeIdChangeOperation(nodeId, newId));
- }
-
- @Override
- public synchronized void nodeCreated(Object nodeId) {
- stateLog.nodeCreated(nodeId);
- processChange(new NodeCreateOperation(nodeId));
- }
-
- @Override
- public synchronized void nodeRemoved(Object nodeId) {
- stateLog.nodeRemoved(nodeId);
- processChange(new NodeDeleteOperation(nodeId));
- }
-
- @Override
- public synchronized void nodePropertyChanged(
- Object nodeId,
- String property,
- Object oldValue,
- Object newValue) {
-
- stateLog.nodePropertyChanged(nodeId, property, oldValue, newValue);
- processChange(new NodePropertyChangeOperation(
- nodeId,
- property,
- oldValue,
- newValue));
- }
-
- @Override
- public synchronized void arcCreated(Object nodeId, Object targetNodeId, Object arcId) {
- stateLog.arcCreated(nodeId, targetNodeId, arcId);
- processChange(new ArcCreateOperation(nodeId, targetNodeId, arcId));
- }
-
- @Override
- public synchronized void arcDeleted(Object nodeId, Object targetNodeId, Object arcId) {
- stateLog.arcDeleted(nodeId, targetNodeId, arcId);
- processChange(new ArcDeleteOperation(nodeId, targetNodeId, arcId));
- }
-
- // ****** helper methods ******
- // =====================================================
-
- private void processChange(GraphDiff diff) {
- changeLog.addOperation(diff);
-
- if (changeEventsEnabled) {
- context.fireDataChannelChanged(context, diff);
- }
- }
-
- /**
- * Wraps GraphDiff in a GraphEvent and sends it via EventManager with specified
- * subject.
- */
- void send(GraphDiff diff, EventSubject subject, Object eventSource) {
- EventManager manager = (context.getChannel() != null) ? context
- .getChannel()
- .getEventManager() : null;
-
- if (manager != null) {
- GraphEvent e = new GraphEvent(context, eventSource, diff);
- manager.postEvent(e, subject);
- }
- }
-
- void reset() {
- changeLog.reset();
-
- if (deadIds != null) {
- // unregister dead ids...
- for (final Object deadId : deadIds) {
- nodes.remove(deadId);
- }
-
- deadIds = null;
- }
- }
-
- Collection<Object> deadIds() {
- if (deadIds == null) {
- deadIds = new ArrayList<>();
- }
-
- return deadIds;
- }
-
- /**
- * This change handler is used to perform rollback actions for Cayenne context
- */
- class RollbackChangeHandler implements GraphChangeHandler {
-
- public void arcCreated(Object nodeId, Object targetNodeId, Object arcId) {
- context.mergeHandler.arcCreated(nodeId, targetNodeId, arcId);
- CayenneContextGraphManager.this.arcCreated(nodeId, targetNodeId, arcId);
- }
-
- public void arcDeleted(Object nodeId, Object targetNodeId, Object arcId) {
- context.mergeHandler.arcDeleted(nodeId, targetNodeId, arcId);
- CayenneContextGraphManager.this.arcDeleted(nodeId, targetNodeId, arcId);
- }
-
- public void nodeCreated(Object nodeId) {
- CayenneContextGraphManager.this.nodeCreated(nodeId);
- }
-
- public void nodeIdChanged(Object nodeId, Object newId) {
- CayenneContextGraphManager.this.nodeIdChanged(nodeId, newId);
- }
-
- /**
- * Need to write property directly to this context
- */
- public void nodePropertyChanged(
- Object nodeId,
- String property,
- Object oldValue,
- Object newValue) {
- context.mergeHandler
- .nodePropertyChanged(nodeId, property, oldValue, newValue);
- CayenneContextGraphManager.this.nodePropertyChanged(
- nodeId,
- property,
- oldValue,
- newValue);
- }
-
- public void nodeRemoved(Object nodeId) {
- CayenneContextGraphManager.this.nodeRemoved(nodeId);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/38f37d79/cayenne-server/src/main/java/org/apache/cayenne/CayenneContextMergeHandler.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/CayenneContextMergeHandler.java b/cayenne-server/src/main/java/org/apache/cayenne/CayenneContextMergeHandler.java
deleted file mode 100644
index f490128..0000000
--- a/cayenne-server/src/main/java/org/apache/cayenne/CayenneContextMergeHandler.java
+++ /dev/null
@@ -1,274 +0,0 @@
-/*****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- ****************************************************************/
-
-package org.apache.cayenne;
-
-import org.apache.cayenne.graph.GraphChangeHandler;
-import org.apache.cayenne.graph.GraphDiff;
-import org.apache.cayenne.graph.GraphEvent;
-import org.apache.cayenne.reflect.ArcProperty;
-import org.apache.cayenne.reflect.ClassDescriptor;
-import org.apache.cayenne.reflect.PropertyDescriptor;
-import org.apache.cayenne.reflect.ToManyProperty;
-import org.apache.cayenne.util.Util;
-
-/**
- * An object that merges "backdoor" modifications of the object graph coming from the
- * underlying DataChannel. When doing an update, CayenneContextMergeHandler blocks
- * broadcasting of GraphManager events.
- *
- * @since 1.2
- */
-class CayenneContextMergeHandler implements GraphChangeHandler, DataChannelListener {
-
- CayenneContext context;
- boolean active;
-
- CayenneContextMergeHandler(CayenneContext context) {
- this.context = context;
- this.active = true;
- }
-
- // ******* DataChannelListener methods *******
-
- public void graphChanged(final GraphEvent e) {
- // process flush
- if (shouldProcessEvent(e) && e.getDiff() != null) {
- runWithEventsDisabled(new Runnable() {
-
- public void run() {
- e.getDiff().apply(CayenneContextMergeHandler.this);
-
- }
- });
-
- // post event outside of "execute" to make sure it is sent
- repostAfterMerge(e);
- }
- }
-
- public void graphFlushed(final GraphEvent e) {
- // TODO (Andrus, 10/17/2005) - there are a few problems with commit processing:
-
- // 1. Event mechanism reliability:
- // - events may come out of order (commit and then preceeding flush)
- // - events may be missing all together (commit arrived, while prior flush did
- // not)
- // Possible solution - an "event_version_id" to be used for optimistic locking
-
- // 2. We don't know if our own dirty objects were committed or not...
- // For now we will simply merge the changes, and keep the context dirty
-
- if (shouldProcessEvent(e)) {
-
- runWithEventsDisabled(new Runnable() {
-
- public void run() {
-
- if (e.getDiff() != null) {
- e.getDiff().apply(CayenneContextMergeHandler.this);
- }
- }
- });
-
- // post event outside of "execute" to make sure it is sent
- repostAfterMerge(e);
- }
- }
-
- public void graphRolledback(final GraphEvent e) {
-
- // TODO: andrus, 3/29/2007: per CAY-771, if a LOCAL peer context posted the event,
- // just ignore it, however if the REMOTE peer reverted the parent remote
- // DataContext, we need to invalidate stale committed objects...
- }
-
- // ******* End DataChannelListener methods *******
-
- void repostAfterMerge(GraphEvent originalEvent) {
- // though the subject is CHANGE, "merge" events are really lifecycle.
- if (context.isLifecycleEventsEnabled()) {
- context.fireDataChannelChanged(originalEvent.getSource(), originalEvent.getDiff());
- }
- }
-
- /**
- * Executes merging of the external diff.
- */
- void merge(final GraphDiff diff) {
- runWithEventsDisabled(new Runnable() {
-
- public void run() {
- diff.apply(CayenneContextMergeHandler.this);
- }
- });
- }
-
- // ******* GraphChangeHandler methods *********
-
- public void nodeIdChanged(Object nodeId, Object newId) {
- // do not unregister the node just yet... only put replaced id in deadIds to
- // remove it later. Otherwise stored operations will not work
- Object node = context.internalGraphManager().getNode(nodeId);
-
- if (node != null) {
- context.internalGraphManager().deadIds().add(nodeId);
- context.internalGraphManager().registerNode(newId, node);
-
- if (node instanceof Persistent) {
- // inject new id
- ((Persistent) node).setObjectId((ObjectId) newId);
- }
- }
- }
-
- public void nodeCreated(Object nodeId) {
- // ignore
- }
-
- public void nodeRemoved(Object nodeId) {
- context.getGraphManager().unregisterNode(nodeId);
- }
-
- public void nodePropertyChanged(
- Object nodeId,
- String property,
- Object oldValue,
- Object newValue) {
-
- Object object = context.internalGraphManager().getNode(nodeId);
- if (object != null) {
-
- // do not override local changes....
- PropertyDescriptor p = propertyForId(nodeId, property);
- if (Util.nullSafeEquals(p.readPropertyDirectly(object), oldValue)) {
-
- p.writePropertyDirectly(object, oldValue, newValue);
- }
- }
- }
-
- public void arcCreated(Object nodeId, Object targetNodeId, Object arcId) {
- // null source or target likely means the object is not faulted yet... Faults
- // shouldn't get disturbed by adding/removing arcs
-
- Object source = context.internalGraphManager().getNode(nodeId);
- if (source == null) {
- // no need to connect non-existent object
- return;
- }
-
- // TODO (Andrus, 10/17/2005) - check for local modifications to avoid
- // overwriting...
-
- ArcProperty p = (ArcProperty) propertyForId(nodeId, arcId.toString());
- if (p.isFault(source)) {
- return;
- }
-
- Object target = context.internalGraphManager().getNode(targetNodeId);
- if (target == null) {
- target = context.createFault((ObjectId) targetNodeId);
- }
-
- try {
- if (p instanceof ToManyProperty) {
- ((ToManyProperty) p).addTargetDirectly(source, target);
- }
- else {
- p.writePropertyDirectly(source, null, target);
- }
- }
- finally {
- }
- }
-
- public void arcDeleted(Object nodeId, Object targetNodeId, Object arcId) {
-
- // null source or target likely means the object is not faulted yet... Faults
- // shouldn't get disturbed by adding/removing arcs
-
- Object source = context.internalGraphManager().getNode(nodeId);
- if (source == null) {
- // no need to disconnect non-existent object
- return;
- }
-
- // (see "TODO" in 'arcCreated')
- ArcProperty p = (ArcProperty) propertyForId(nodeId, arcId.toString());
- if (p.isFault(source)) {
- return;
- }
-
- Object target = context.internalGraphManager().getNode(targetNodeId);
- if (target == null) {
- target = context.createFault((ObjectId) targetNodeId);
- }
-
- try {
- if (p instanceof ToManyProperty) {
- ((ToManyProperty) p).removeTargetDirectly(source, target);
- }
- else {
- p.writePropertyDirectly(source, target, null);
- }
- }
- finally {
- }
- }
-
- private PropertyDescriptor propertyForId(Object nodeId, String propertyName) {
- ClassDescriptor descriptor = context.getEntityResolver().getClassDescriptor(
- ((ObjectId) nodeId).getEntityName());
- return descriptor.getProperty(propertyName);
- }
-
- // Returns true if this object is active; an event came from our channel, but did not
- // originate in it.
- boolean shouldProcessEvent(GraphEvent e) {
- // only process events that came from our channel, but did not originate in it
- // (i.e. likely posted by EventBridge)
- return active
- && e.getSource() == context.getChannel()
- && e.getPostedBy() != context
- && e.getPostedBy() != context.getChannel();
- }
-
- // executes a closure, disabling ObjectContext events for the duration of the
- // execution.
-
- private void runWithEventsDisabled(Runnable closure) {
-
- synchronized (context.internalGraphManager()) {
- boolean changeEventsEnabled = context.internalGraphManager().changeEventsEnabled;
- context.internalGraphManager().changeEventsEnabled = false;
-
- boolean lifecycleEventsEnabled = context.internalGraphManager().lifecycleEventsEnabled;
- context.internalGraphManager().lifecycleEventsEnabled = false;
-
- try {
- closure.run();
- }
- finally {
- context.internalGraphManager().changeEventsEnabled = changeEventsEnabled;
- context.internalGraphManager().lifecycleEventsEnabled = lifecycleEventsEnabled;
- }
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/38f37d79/cayenne-server/src/main/java/org/apache/cayenne/CayenneContextQueryAction.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/CayenneContextQueryAction.java b/cayenne-server/src/main/java/org/apache/cayenne/CayenneContextQueryAction.java
deleted file mode 100644
index e0b693c..0000000
--- a/cayenne-server/src/main/java/org/apache/cayenne/CayenneContextQueryAction.java
+++ /dev/null
@@ -1,186 +0,0 @@
-/*****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- ****************************************************************/
-
-package org.apache.cayenne;
-
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-
-import org.apache.cayenne.cache.QueryCacheEntryFactory;
-import org.apache.cayenne.map.EntityResolver;
-import org.apache.cayenne.query.Query;
-import org.apache.cayenne.query.RefreshQuery;
-import org.apache.cayenne.reflect.AttributeProperty;
-import org.apache.cayenne.reflect.ClassDescriptor;
-import org.apache.cayenne.reflect.PropertyVisitor;
-import org.apache.cayenne.reflect.ToManyProperty;
-import org.apache.cayenne.reflect.ToOneProperty;
-import org.apache.cayenne.remote.RemoteIncrementalFaultList;
-import org.apache.cayenne.util.ListResponse;
-import org.apache.cayenne.util.ObjectContextQueryAction;
-
-/**
- * @since 1.2
- */
-class CayenneContextQueryAction extends ObjectContextQueryAction {
-
- CayenneContextQueryAction(CayenneContext actingContext, ObjectContext targetContext,
- Query query) {
- super(actingContext, targetContext, query);
- }
-
- @Override
- protected boolean interceptPaginatedQuery() {
- if (metadata.getPageSize() > 0) {
- response = new ListResponse(new RemoteIncrementalFaultList(
- actingContext,
- query));
- return DONE;
- }
-
- return !DONE;
- }
-
- @Override
- protected QueryCacheEntryFactory getCacheObjectFactory() {
- return new QueryCacheEntryFactory() {
-
- public List createObject() {
- if (interceptPaginatedQuery() != DONE) {
- runQuery();
- }
- return response.firstList();
- }
- };
- }
-
- @Override
- protected boolean interceptRefreshQuery() {
- if (query instanceof RefreshQuery) {
- RefreshQuery refreshQuery = (RefreshQuery) query;
-
- CayenneContext context = (CayenneContext) actingContext;
-
- // handle 4 separate scenarios, but do not combine them as it will be
- // unclear how to handle cascading behavior
-
- // 1. refresh all
- if (refreshQuery.isRefreshAll()) {
-
- invalidateLocally(context.internalGraphManager(), context
- .internalGraphManager()
- .registeredNodes()
- .iterator());
- context.getQueryCache().clear();
-
- // cascade
- return !DONE;
- }
-
- // 2. invalidate object collection
- Collection<?> objects = refreshQuery.getObjects();
- if (objects != null && !objects.isEmpty()) {
-
- invalidateLocally(context.internalGraphManager(), objects.iterator());
-
- // cascade
- return !DONE;
- }
-
- // 3. refresh query - have to do it eagerly to refresh the objects involved
- if (refreshQuery.getQuery() != null) {
- Query cachedQuery = refreshQuery.getQuery();
-
- String cacheKey = cachedQuery
- .getMetaData(context.getEntityResolver())
- .getCacheKey();
- context.getQueryCache().remove(cacheKey);
-
- this.response = context.performGenericQuery(cachedQuery);
-
- // do not cascade to avoid running query twice
- return DONE;
- }
-
- // 4. refresh groups...
- if (refreshQuery.getGroupKeys() != null
- && refreshQuery.getGroupKeys().length > 0) {
-
- String[] groups = refreshQuery.getGroupKeys();
- for (String group : groups) {
- context.getQueryCache().removeGroup(group);
- }
-
- // cascade group invalidation
- return !DONE;
- }
- }
-
- return !DONE;
- }
-
- private void invalidateLocally(CayenneContextGraphManager graphManager, Iterator<?> it) {
- if (!it.hasNext()) {
- return;
- }
-
- EntityResolver resolver = actingContext.getEntityResolver();
-
- while (it.hasNext()) {
- final Persistent object = (Persistent) it.next();
-
- // we don't care about NEW objects,
- // but we still do care about HOLLOW, since snapshot might still be
- // present
- if (object.getPersistenceState() == PersistenceState.NEW) {
- continue;
- }
-
- ObjectId id = object.getObjectId();
-
- // per CAY-1082 ROP objects (unlike CayenneDataObject) require all
- // relationship faults invalidation.
- ClassDescriptor descriptor = resolver.getClassDescriptor(id.getEntityName());
- PropertyVisitor arcInvalidator = new PropertyVisitor() {
-
- public boolean visitAttribute(AttributeProperty property) {
- return true;
- }
-
- public boolean visitToMany(ToManyProperty property) {
- property.invalidate(object);
- return true;
- }
-
- public boolean visitToOne(ToOneProperty property) {
- property.invalidate(object);
- return true;
- }
- };
-
- descriptor.visitProperties(arcInvalidator);
- object.setPersistenceState(PersistenceState.HOLLOW);
-
- // remove cached changes
- graphManager.changeLog.unregisterNode(id);
- graphManager.stateLog.unregisterNode(id);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/38f37d79/cayenne-server/src/main/java/org/apache/cayenne/remote/BootstrapMessage.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/remote/BootstrapMessage.java b/cayenne-server/src/main/java/org/apache/cayenne/remote/BootstrapMessage.java
deleted file mode 100644
index 26f2f1b..0000000
--- a/cayenne-server/src/main/java/org/apache/cayenne/remote/BootstrapMessage.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- ****************************************************************/
-
-package org.apache.cayenne.remote;
-
-/**
- * A message sent to a remote service to request Cayenne mapping info.
- *
- * @since 1.2
- */
-public class BootstrapMessage implements ClientMessage {
-
- /**
- * Returns a description of the type of message. In this case always "Bootstrap".
- */
- @Override
- public String toString() {
- return "Bootstrap";
- }
-}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/38f37d79/cayenne-server/src/main/java/org/apache/cayenne/remote/ClientMessage.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/remote/ClientMessage.java b/cayenne-server/src/main/java/org/apache/cayenne/remote/ClientMessage.java
deleted file mode 100644
index e0740b3..0000000
--- a/cayenne-server/src/main/java/org/apache/cayenne/remote/ClientMessage.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- ****************************************************************/
-
-package org.apache.cayenne.remote;
-
-import java.io.Serializable;
-
-/**
- * A tag interface representing a message sent by a remote client to Cayenne service.
- *
- * @since 1.2
- */
-public interface ClientMessage extends Serializable {
-
-}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/38f37d79/cayenne-server/src/main/java/org/apache/cayenne/remote/IncrementalQuery.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/remote/IncrementalQuery.java b/cayenne-server/src/main/java/org/apache/cayenne/remote/IncrementalQuery.java
deleted file mode 100644
index 51c7946..0000000
--- a/cayenne-server/src/main/java/org/apache/cayenne/remote/IncrementalQuery.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- ****************************************************************/
-
-package org.apache.cayenne.remote;
-
-import org.apache.cayenne.map.DataMap;
-import org.apache.cayenne.map.EntityResolver;
-import org.apache.cayenne.query.Query;
-import org.apache.cayenne.query.QueryMetadata;
-import org.apache.cayenne.query.QueryMetadataProxy;
-import org.apache.cayenne.query.QueryRouter;
-import org.apache.cayenne.query.SQLAction;
-import org.apache.cayenne.query.SQLActionVisitor;
-
-/**
- * A client wrapper for the incremental query that overrides the metadata to ensure that
- * query result is cached on the server, so that subranges could be retrieved at a later
- * time.
- *
- * @since 1.2
- */
-class IncrementalQuery implements Query {
-
- private Query query;
- private String cacheKey;
-
- IncrementalQuery(Query query, String cacheKey) {
- this.query = query;
- this.cacheKey = cacheKey;
- }
-
- public QueryMetadata getMetaData(EntityResolver resolver) {
- final QueryMetadata metadata = query.getMetaData(resolver);
-
- // the way paginated queries work on the server is that they are never cached
- // (IncrementalFaultList interception happens before cache interception). So
- // overriding caching settings in the metadata will only affect
- // ClientServerChannel behavior
- return new QueryMetadataProxy(metadata) {
- public Query getOriginatingQuery() {
- return null;
- }
-
- public String getCacheKey() {
- return cacheKey;
- }
- };
- }
-
- public void route(QueryRouter router, EntityResolver resolver, Query substitutedQuery) {
- query.route(router, resolver, substitutedQuery);
- }
-
- public SQLAction createSQLAction(SQLActionVisitor visitor) {
- return query.createSQLAction(visitor);
- }
-}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/38f37d79/cayenne-server/src/main/java/org/apache/cayenne/remote/IncrementalSelectQuery.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/remote/IncrementalSelectQuery.java b/cayenne-server/src/main/java/org/apache/cayenne/remote/IncrementalSelectQuery.java
deleted file mode 100644
index 9b6f563..0000000
--- a/cayenne-server/src/main/java/org/apache/cayenne/remote/IncrementalSelectQuery.java
+++ /dev/null
@@ -1,300 +0,0 @@
-/*****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- ****************************************************************/
-package org.apache.cayenne.remote;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.cayenne.ObjectContext;
-import org.apache.cayenne.ResultBatchIterator;
-import org.apache.cayenne.ResultIterator;
-import org.apache.cayenne.ResultIteratorCallback;
-import org.apache.cayenne.access.IncrementalFaultList;
-import org.apache.cayenne.exp.Expression;
-import org.apache.cayenne.map.EntityResolver;
-import org.apache.cayenne.query.Ordering;
-import org.apache.cayenne.query.PrefetchTreeNode;
-import org.apache.cayenne.query.Query;
-import org.apache.cayenne.query.QueryMetadata;
-import org.apache.cayenne.query.QueryMetadataProxy;
-import org.apache.cayenne.query.QueryRouter;
-import org.apache.cayenne.query.SQLAction;
-import org.apache.cayenne.query.SQLActionVisitor;
-import org.apache.cayenne.query.SelectQuery;
-import org.apache.cayenne.query.SortOrder;
-import org.apache.cayenne.util.XMLEncoder;
-
-/**
- * A SelectQuery decorator that overrides the metadata to ensure that query
- * result is cached on the server, so that subranges could be retrieved at a
- * later time. Note that a special decorator that is a subclass of SelectQuery
- * is needed so that {@link IncrementalFaultList} on the server-side could apply
- * SelectQuery-specific optimizations.
- *
- * @since 3.0
- */
-class IncrementalSelectQuery<T> extends SelectQuery<T> {
-
- private SelectQuery<T> query;
- private String cacheKey;
-
- IncrementalSelectQuery(SelectQuery<T> delegate, String cacheKey) {
- this.query = delegate;
- this.cacheKey = cacheKey;
- }
-
- @Override
- public QueryMetadata getMetaData(EntityResolver resolver) {
- final QueryMetadata metadata = query.getMetaData(resolver);
-
- // the way paginated queries work on the server is that they are never
- // cached
- // (IncrementalFaultList interception happens before cache
- // interception). So
- // overriding caching settings in the metadata will only affect
- // ClientServerChannel behavior
- return new QueryMetadataProxy(metadata) {
- public Query getOriginatingQuery() {
- return null;
- }
-
- public String getCacheKey() {
- return cacheKey;
- }
- };
- }
-
- @Override
- public void addOrdering(Ordering ordering) {
- query.addOrdering(ordering);
- }
-
- @Override
- public void addOrdering(String sortPathSpec, SortOrder order) {
- query.addOrdering(sortPathSpec, order);
- }
-
- @Override
- public void addOrderings(Collection<? extends Ordering> orderings) {
- query.addOrderings(orderings);
- }
-
- @Override
- public PrefetchTreeNode addPrefetch(String prefetchPath) {
- return query.addPrefetch(prefetchPath);
- }
-
- @Override
- public void andQualifier(Expression e) {
- query.andQualifier(e);
- }
-
- @Override
- public void clearOrderings() {
- query.clearOrderings();
- }
-
- @Override
- public void clearPrefetches() {
- query.clearPrefetches();
- }
-
- @Override
- public SelectQuery<T> createQuery(Map<String, ?> parameters) {
- return query.createQuery(parameters);
- }
-
- @Override
- public SQLAction createSQLAction(SQLActionVisitor visitor) {
- return query.createSQLAction(visitor);
- }
-
- @Override
- public boolean equals(Object obj) {
- return query.equals(obj);
- }
-
- /**
- * @since 4.0
- */
- @Override
- public String getCacheGroup() {
- return super.getCacheGroup();
- }
-
- @Override
- public int getFetchLimit() {
- return query.getFetchLimit();
- }
-
- @Override
- public List<Ordering> getOrderings() {
- return query.getOrderings();
- }
-
- @Override
- public int getPageSize() {
- return query.getPageSize();
- }
-
- @Override
- public PrefetchTreeNode getPrefetchTree() {
- return query.getPrefetchTree();
- }
-
- @Override
- public Expression getQualifier() {
- return query.getQualifier();
- }
-
- @Override
- public Object getRoot() {
- return query.getRoot();
- }
-
- @Override
- public int hashCode() {
- return query.hashCode();
- }
-
- @Override
- public void initWithProperties(Map<String, ?> properties) {
- query.initWithProperties(properties);
- }
-
- @Override
- public boolean isDistinct() {
- return query.isDistinct();
- }
-
- @Override
- public boolean isFetchingDataRows() {
- return query.isFetchingDataRows();
- }
-
- @Override
- public void orQualifier(Expression e) {
- query.orQualifier(e);
- }
-
- @Override
- public SelectQuery<T> queryWithParameters(Map<String, ?> parameters, boolean pruneMissing) {
- return query.queryWithParameters(parameters, pruneMissing);
- }
-
- @Override
- public SelectQuery<T> queryWithParameters(Map<String, ?> parameters) {
- return query.queryWithParameters(parameters);
- }
-
- @Override
- public void removeOrdering(Ordering ordering) {
- query.removeOrdering(ordering);
- }
-
- @Override
- public void removePrefetch(String prefetchPath) {
- query.removePrefetch(prefetchPath);
- }
-
- @Override
- public void route(QueryRouter router, EntityResolver resolver, Query substitutedQuery) {
- query.route(router, resolver, substitutedQuery);
- }
-
- /**
- * @since 4.0
- */
- @Override
- public void setCacheGroup(String cacheGroup) {
- query.setCacheGroup(cacheGroup);
- }
-
- @Override
- public void setDistinct(boolean distinct) {
- query.setDistinct(distinct);
- }
-
- @SuppressWarnings("deprecation")
- @Override
- public void setFetchingDataRows(boolean flag) {
- query.setFetchingDataRows(flag);
- }
-
- @Override
- public void setFetchLimit(int fetchLimit) {
- query.setFetchLimit(fetchLimit);
- }
-
- @Override
- public void setPageSize(int pageSize) {
- query.setPageSize(pageSize);
- }
-
- @Override
- public void setPrefetchTree(PrefetchTreeNode prefetchTree) {
- query.setPrefetchTree(prefetchTree);
- }
-
- @Override
- public void setQualifier(Expression qualifier) {
- query.setQualifier(qualifier);
- }
-
- @Override
- public void setRoot(Object value) {
- query.setRoot(value);
- }
-
- @Override
- public String toString() {
- return query.toString();
- }
-
- @Override
- public List<T> select(ObjectContext context) {
- return query.select(context);
- }
-
- @Override
- public T selectOne(ObjectContext context) {
- return query.selectOne(context);
- }
-
- @Override
- public T selectFirst(ObjectContext context) {
- return query.selectFirst(context);
- }
-
- @Override
- public void iterate(ObjectContext context, ResultIteratorCallback<T> callback) {
- query.iterate(context, callback);
- }
-
- @Override
- public ResultIterator<T> iterator(ObjectContext context) {
- return query.iterator(context);
- }
-
- @Override
- public ResultBatchIterator<T> batchIterator(ObjectContext context, int size) {
- return query.batchIterator(context, size);
- }
-}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/38f37d79/cayenne-server/src/main/java/org/apache/cayenne/remote/QueryMessage.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/remote/QueryMessage.java b/cayenne-server/src/main/java/org/apache/cayenne/remote/QueryMessage.java
deleted file mode 100644
index 3c8b4d5..0000000
--- a/cayenne-server/src/main/java/org/apache/cayenne/remote/QueryMessage.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- ****************************************************************/
-
-package org.apache.cayenne.remote;
-
-import org.apache.cayenne.query.Query;
-
-/**
- * A message passed to a DataChannel to request a query execution with result returned as
- * QueryResponse.
- *
- * @since 1.2
- */
-public class QueryMessage implements ClientMessage {
-
- protected Query query;
-
- // for hessian serialization
- @SuppressWarnings("unused")
- private QueryMessage() {
-
- }
-
- public QueryMessage(Query query) {
- this.query = query;
- }
-
- public Query getQuery() {
- return query;
- }
-
- /**
- * Returns a description of the type of message. In this case always "Query".
- */
- @Override
- public String toString() {
- return "Query";
- }
-}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/38f37d79/cayenne-server/src/main/java/org/apache/cayenne/remote/RangeQuery.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/remote/RangeQuery.java b/cayenne-server/src/main/java/org/apache/cayenne/remote/RangeQuery.java
deleted file mode 100644
index f2b5e78..0000000
--- a/cayenne-server/src/main/java/org/apache/cayenne/remote/RangeQuery.java
+++ /dev/null
@@ -1,156 +0,0 @@
-/*****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- ****************************************************************/
-
-package org.apache.cayenne.remote;
-
-import java.util.List;
-import java.util.Map;
-
-import org.apache.cayenne.map.DataMap;
-import org.apache.cayenne.map.DbEntity;
-import org.apache.cayenne.map.EntityResolver;
-import org.apache.cayenne.map.ObjEntity;
-import org.apache.cayenne.map.Procedure;
-import org.apache.cayenne.query.Query;
-import org.apache.cayenne.query.QueryCacheStrategy;
-import org.apache.cayenne.query.QueryMetadata;
-import org.apache.cayenne.query.QueryMetadataProxy;
-import org.apache.cayenne.query.QueryRouter;
-import org.apache.cayenne.query.SQLAction;
-import org.apache.cayenne.query.SQLActionVisitor;
-import org.apache.cayenne.reflect.ClassDescriptor;
-
-/**
- * A Query that fetches a range of objects from a previously fetched server-side paginated
- * list. This query is client-only and can't be executed on the server.
- *
- * @since 1.2
- */
-class RangeQuery implements Query {
-
- private String cacheKey;
- private int fetchOffset;
- private int fetchLimit;
- private Query originatingQuery;
-
- // exists for hessian serialization.
- @SuppressWarnings("unused")
- private RangeQuery() {
-
- }
-
- /**
- * Creates a query that returns a single page from an existing cached server-side
- * result list.
- */
- RangeQuery(String cacheKey, int fetchStartIndex, int fetchLimit,
- Query originatingQuery) {
- this.cacheKey = cacheKey;
- this.fetchOffset = fetchStartIndex;
- this.fetchLimit = fetchLimit;
- this.originatingQuery = originatingQuery;
- }
-
- public QueryMetadata getMetaData(EntityResolver resolver) {
- final QueryMetadata originatingMetadata = originatingQuery.getMetaData(resolver);
-
- return new QueryMetadataProxy(originatingMetadata) {
-
- public Query getOriginatingQuery() {
- return originatingQuery;
- }
-
- public List<Object> getResultSetMapping() {
- return null;
- }
-
- public boolean isSingleResultSetMapping() {
- return false;
- }
-
- public String getCacheKey() {
- return cacheKey;
- }
-
- public String getCacheGroup() {
- return null;
- }
-
- public int getFetchOffset() {
- return fetchOffset;
- }
-
- public int getFetchLimit() {
- return fetchLimit;
- }
-
- public int getPageSize() {
- return 0;
- }
-
- /**
- * @since 3.0
- */
- public QueryCacheStrategy getCacheStrategy() {
- return QueryCacheStrategy.getDefaultStrategy();
- }
-
- public DataMap getDataMap() {
- throw new UnsupportedOperationException();
- }
-
- public DbEntity getDbEntity() {
- throw new UnsupportedOperationException();
- }
-
- public ObjEntity getObjEntity() {
- throw new UnsupportedOperationException();
- }
-
- public ClassDescriptor getClassDescriptor() {
- throw new UnsupportedOperationException();
- }
-
- public Procedure getProcedure() {
- throw new UnsupportedOperationException();
- }
-
- public Map<String, String> getPathSplitAliases() {
- throw new UnsupportedOperationException();
- }
-
- public boolean isRefreshingObjects() {
- throw new UnsupportedOperationException();
- }
-
- public int getStatementFetchSize() {
- return 0;
- }
- };
- }
-
- public SQLAction createSQLAction(SQLActionVisitor visitor) {
- throw new UnsupportedOperationException();
- }
-
- public void route(QueryRouter router, EntityResolver resolver, Query substitutedQuery) {
- throw new UnsupportedOperationException();
- }
-
-}