/** * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Eike Stepper - initial API and implementation * Simon McDuff - maintenance * Victor Roldan Betancort - maintenance */ package org.eclipse.emf.cdo.view; import org.eclipse.emf.cdo.CDOAdapter; import org.eclipse.emf.cdo.CDOInvalidationNotification; import org.eclipse.emf.cdo.CDOObject; import org.eclipse.emf.cdo.CDOState; import org.eclipse.emf.cdo.common.CDOCommonView; import org.eclipse.emf.cdo.common.id.CDOID; import org.eclipse.emf.cdo.eresource.CDOResource; import org.eclipse.emf.cdo.eresource.CDOResourceFolder; import org.eclipse.emf.cdo.eresource.CDOResourceNode; import org.eclipse.emf.cdo.session.CDOSession; import org.eclipse.emf.cdo.transaction.CDOTransaction; import org.eclipse.emf.cdo.util.ReadOnlyException; import org.eclipse.net4j.util.collection.CloseableIterator; import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType; import org.eclipse.net4j.util.event.INotifier; import org.eclipse.net4j.util.options.IOptions; import org.eclipse.net4j.util.options.IOptionsContainer; import org.eclipse.net4j.util.options.IOptionsEvent; import org.eclipse.net4j.util.ref.ReferenceType; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.resource.ResourceSet; import org.eclipse.emf.ecore.resource.URIHandler; import java.util.Collection; import java.util.List; import java.util.concurrent.locks.ReentrantLock; /** * A read-only view to the current (i.e. latest) state of the object graph in the repository of the underlying * {@link CDOSession session}. *

* Objects that are accessed through this view are unchangeable for the client. Each attempt to call a mutator on one of * these objects or one of their reference collections will result in a {@link ReadOnlyException} being thrown * immediately. *

* A view is opened through API of the underlying session like this: * *

 *   CDOSession session = ...
 *   CDOView view = session.openView();
 *   ...
 * 
* * CDOView instances must not be accessed through concurrent client threads. *

* Since a CDOObject, in a {@link CDOState#TRANSIENT non-TRANSIENT} state, is only meaningful in combination with its * dedicated view they must also not be accessed through concurrent client threads. Please note that at arbitrary times * an arbitrary number of framework background threads are allowed to use and modify a CDOview and its CDOObjects. * Whenever you are iterating over a number of CDOObjects and need to ensure that they are not modified by the framework * at the same time it is strongly recommended to acquire the {@link #getLock() view lock} and protect your code * appropriately. * * @author Eike Stepper * @noimplement This interface is not intended to be implemented by clients. * @since 2.0 */ public interface CDOView extends CDOCommonView, INotifier, IOptionsContainer { /** * Returns the {@link CDOSession session} this view was opened by. * * @return The session this view was opened by, or null if this view is closed. * @see #close() * @see #isClosed() * @see CDOSession#openView() * @see CDOSession#openView(ResourceSet) * @see CDOSession#openAudit(long) * @see CDOSession#openAudit(ResourceSet, long) * @see CDOSession#openTransaction() * @see CDOSession#openTransaction(ResourceSet) */ public CDOSession getSession(); /** * Returns the {@link CDOViewSet view set} this view is associated with. * * @return The view set this view is associated with, never null. * @see CDOViewSet#getViews() */ public CDOViewSet getViewSet(); /** * Returns the {@link ResourceSet resource set} this view is associated with. *

* Same as calling getViewSet().getResourceSet(). * * @see CDOViewSet#getResourceSet() */ public ResourceSet getResourceSet(); /** * @deprecated This API is provisional and subject to change or removal. */ @Deprecated public URIHandler getURIHandler(); /** * Returns a reentrant lock that can be used to prevent the framework from writing to any object in this view (as it * is caused, for example, by passive updates). *

* Acquiring this lock provides a means to safely iterate over multiple model elements without being affected by * unanticipated remote updates, like in the following example: * *

   *    CDOResource resource = view.getResource("/orders/order-4711");
   *    PurchaseOrder order = (PurchaseOrder)resource.getContents().get(0);
   *    ReentrantLock lock = view.getLock();
   *    if (!lock.tryLock(5L, TimeUnit.SECONDS))
   *    {
   *      throw new TimeoutException();
   *    }
   *    try
   *    {
   *      float sum = 0;
   *      for (OrderDetail detail : order.getOrderDetails())
   *      {
   *        sum += detail.getPrice();
   *      }
   *      System.out.println("Sum: " + sum);
   *    }
   *    finally
   *    {
   *      lock.unlock();
   *    }
   *  }
   * 
* * Note that this method really just returns the lock instance but does not acquire the lock! The above example * acquires the lock with a timeout that expires after five seconds. */ public ReentrantLock getLock(); /** * Returns always false. *

* This method has a special implementation in {@link CDOTransaction} as well. * * @see CDOTransaction#isDirty() */ public boolean isDirty(); /** * Returns always false. *

* This method has a special implementation in {@link CDOTransaction} as well. * * @see CDOTransaction#hasConflict() */ public boolean hasConflict(); /** * Returns true if a resource with the given path exists in the repository, false. * * @see #getResource(String, boolean) */ public boolean hasResource(String path); /** * @see ResourceSet#getResource(URI, boolean) */ public CDOResource getResource(String path, boolean loadOnDemand); /** * Same as {@link #getResource(String, boolean) getResource(String, true)}. * * @see ResourceSet#getResource(URI, boolean) */ public CDOResource getResource(String path); /** * Returns the resource node with the given path, or null if no such resource node exists. */ public CDOResourceNode getResourceNode(String path); /** * Returns the root resource of the repository. *

* The root resource is a special resource with only {@link CDOResourceNode CDOResourceNodes} in its contents list. * You can use it as the main entry into the new resource and folder structure. */ public CDOResource getRootResource(); /** * Returns a list of the resources in the given folder with a name equal to or starting with the value of the name * parameter. * * @param folder * The folder to search in, or null for top level resource nodes. * @param name * the name or prefix of the resource nodes to return. * @param exactMatch * true if the complete name of the resource must match, false if only a common * prefix of the name must match. */ public List queryResources(CDOResourceFolder folder, String name, boolean exactMatch); /** * Returns an iterator over the resources in the given folder with a name equal to or starting with the value of the * name parameter. The underlying query will be executed asynchronously. * * @param folder * The folder to search in, or null for top level resource nodes. * @param name * the name or prefix of the resource nodes to return. * @param exactMatch * true if the complete name of the resource must match, false if only a common * prefix of the name must match. */ public CloseableIterator queryResourcesAsync(CDOResourceFolder folder, String name, boolean exactMatch); /** * Returns the object for the given CDOID. * * @param loadOnDemand * whether to create and load the object, if it doesn't already exist. * @return the object resolved by the CDOID if the id is not null, or null if there isn't * one and loadOnDemand is false. */ public CDOObject getObject(CDOID id, boolean loadOnDemand); /** * Returns the object for the given CDOID. *

* Same as getObject(id, true). * * @see getObject(CDOID, boolean) */ public CDOObject getObject(CDOID id); /** * Takes an object from a (possibly) different view and contextifies it for the usage with this view. *

*/ public T getObject(T objectFromDifferentView); /** * Returns true if an {@link CDOObject object} with the given {@link CDOID id} is currently registered in * this view, false otherwise. */ public boolean isObjectRegistered(CDOID id); /** * Reloads the given {@link CDOObject objects} from the repository. */ public int reload(CDOObject... objects); /** * Locks the given objects. Once the objects are locked, they will not be changed remotely or go in conflict state. * * @since 3.0 */ public void lockObjects(Collection objects, LockType lockType, long timeout) throws InterruptedException; /** * Unlocks the given locked objects of this view. */ public void unlockObjects(Collection objects, LockType lockType); /** * Unlocks all locked objects of this view. * * @since 2.0 */ public void unlockObjects(); /** * @since 2.0 */ public CDOQuery createQuery(String language, String queryString); /** * @since 2.0 */ public Options options(); /** * @author Simon McDuff */ public interface Options extends IOptions { /** */ public static final int NO_REVISION_PREFETCHING = 1; /** * Returns the reference type to be used in the internal object cache. * * @return Either {@link ReferenceType#STRONG STRONG}, {@link ReferenceType#SOFT SOFT} or {@link ReferenceType#WEAK * WEAK}. */ public ReferenceType getCacheReferenceType(); /** * Sets the reference type to be used in the internal object cache to either {@link ReferenceType#STRONG STRONG}, * {@link ReferenceType#SOFT SOFT} or {@link ReferenceType#WEAK WEAK}. If null is passed the default * reference type {@link ReferenceType#SOFT SOFT} is set. If the given reference type does not differ from the one * being currently set the new value is ignored and false is returned. Otherwise existing object * references are converted to the new type and true is returned. */ public boolean setCacheReferenceType(ReferenceType referenceType); /** * Returns true if the {@link CDOObject objects} in this view will notify their * {@link org.eclipse.emf.common.notify.Adapter adapters} about the fact that they are invalidated (due to * remote changes), false otherwise. * * @see CDOInvalidationNotification */ public boolean isInvalidationNotificationEnabled(); /** * Specifies whether the {@link CDOObject objects} in this view will notify their * {@link org.eclipse.emf.common.notify.Adapter adapters} about the fact that they are invalidated (due to * remote changes) or not. * * @see CDOInvalidationNotification */ public void setInvalidationNotificationEnabled(boolean enabled); /** * Returns the current set of {@link CDOAdapterPolicy change subscription policies}. * * @return The current set of change subscription policies, never null. * @see #setChangeSubscriptionPolicy(CDOAdapterPolicy) */ public CDOAdapterPolicy[] getChangeSubscriptionPolicies(); /** * Adds a change subscription policy to this view. *

* To activate a policy, you must do the following:
* view.options().addChangeSubscriptionPolicy(CDOChangeSubscriptionPolicy.ALL); *

* To register an object, you must add an adapter to the object in which you are interested:
* eObject.eAdapters().add(myAdapter); *

* By activating this feature, each object having at least one adapter that matches the current policy will be * registered with the server and will be notified for each change occurring in the scope of any other transaction. *

* {@link CDOAdapterPolicy#NONE} - Ignored.
* {@link CDOAdapterPolicy#ALL} - Enabled for all adapters used.
* {@link CDOAdapterPolicy#CDO} - Enabled only for adapters that implement {@link CDOAdapter}.
* Any other class that implement {@link CDOAdapterPolicy} will enable for whatever rules defined in that class. *
*

* If myAdapter in the above example matches the current policy, eObject will be * registered with the server and you will receive all changes from other transaction. *

* When the policy is changed all objects in the cache will automatically be recalculated. *

* You can subscribe to temporary objects. Even if you cannot receive notifications from other * {@link CDOTransaction} for these because they are only local to you, at commit time these objects will be * registered automatically. *

* Note: It can be used with CDOSession.options().setPassiveUpdate(false). In this case, it will * receive changes without having the objects changed. */ public void addChangeSubscriptionPolicy(CDOAdapterPolicy policy); /** * Removes a change subscription policy from this view. */ public void removeChangeSubscriptionPolicy(CDOAdapterPolicy policy); // TODO public CDOAdapterPolicy getStrongReferencePolicy(); /** * Sets the reference type to be used when an adapter is used to an object. *

* When CDOView.setStrongReference(CDOAdapterPolicy.ALL) is used, it is possible that the target object * will be GC. In that case, the adapter will never received notifications. By Default the value is at * CDOAdapterPolicy.ALL */ public void setStrongReferencePolicy(CDOAdapterPolicy policy); /** * Returns the CDORevisionPrefetchingPolicy in used. */ public CDORevisionPrefetchingPolicy getRevisionPrefetchingPolicy(); /** * The CDORevisionPrefetchingPolicy feature of the CDOView allows CDO users to fetch many objects at a time. *

* The difference between the CDOCollectionLoadingPolicy feature and the CDORevisionPrefetchingPolicy feature is * subtle. The CDOCollectionLoadingPolicy feature determines how and when to fetch CDOIDs, while the * CDORevisionPrefetchingPolicy feature determines how and when to resolve CDOIDs (i.e. fetch the target objects). *

* view.options().setRevisionPrefetchingPolicy (CDONet4jUtil.createRevisionPrefetchingPolicy(10)); *

* The end-user could provide its own implementation of the CDORevisionPrefetchingPolicy interface. */ public void setRevisionPrefetchingPolicy(CDORevisionPrefetchingPolicy prefetchingPolicy); public interface CacheReferenceTypeEvent extends IOptionsEvent { } public interface ReferencePolicyEvent extends IOptionsEvent { } public interface ChangeSubscriptionPoliciesEvent extends IOptionsEvent { } public interface InvalidationNotificationEvent extends IOptionsEvent { } public interface RevisionPrefetchingPolicyEvent extends IOptionsEvent { } } }