/** Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016. All rights reserved. Contact: SYSTAP, LLC DBA Blazegraph 2501 Calvert ST NW #106 Washington, DC 20008 licenses@blazegraph.com This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package com.bigdata.gom.gpo; import java.util.Map; import java.util.Set; import org.openrdf.model.Resource; import org.openrdf.model.Statement; import org.openrdf.model.URI; import org.openrdf.model.Value; import com.bigdata.gom.om.IObjectManager; import com.bigdata.gom.skin.GenericSkinRegistry; import com.bigdata.rdf.model.BigdataResource; /** * A generic object has identity and an extensible, loosely-typed property set. * When the value of a property is another generic object, the property models a * directed many-to-one association. Many-to-many linking patterns are modeled * using intermediate objects and a convenience API. Reverse navigation for * associations is automatically aggregated by the association target within a * {@link ILinkSet link set}. Associations and link sets provide an uniform, * efficient and scalable API for object navigation. Link sets may be * {@link ILinkSetIndex indexed }for efficient search. * <p> * * Extensible behavior is realized by wrapping up a generic object within some * application specific interface. Generic object implementations should be * considered as <code>final</code>. Specific backends may support * subclassing but use of subclassing will lock an application into a specific * GOM platform. Instead applications layer additional behavior onto generic * objects using "skins" - see {@link #asClass( Class )}. A skin delegates the * management of persistent state to a backing generic object. The use of skins * provides transparent migration of application code across different GOM * implementations. * <p> * * The generic object model provides transparent and scalable persistence when * using an appropriate backing store. The backing store is selected and * configured using the {@link ObjectManagerFactory}. * <p> */ public interface IGPO extends IGenericSkin // @todo , INativeTransaction? { /* * TODO Need something about the materialized facets. This would need to be * reconciled with the RDFS+ Schema. */ /** * Returns the persistent identity of the generic object. */ BigdataResource getId(); /** * Returns true iff <i>other</i> has the same identity as <i>this</i> * generic object and is in the same {@link IObjectManager} scope (this is * just <code>this == other</code> since the {@link IObjectManager} * guarantees that {@link IGPO}s are canonical for a given {@link Resource} * within the scope of the {@link IObjectManager}). */ boolean equals(Object other); /** * Return the hash code of the identity of the generic object. (The hash * code is NOT based on the internal state of the generic object.) */ int hashCode(); /** * Return the {@link IObjectManager} used to materialize or create this * generic object. */ IObjectManager getObjectManager(); // ************************************************************ // ************************* get / set ************************ // ************************************************************ /* * All methods return mutable collections. Neither the GPO's statement set * nor the reverse link set are pre-materialized. */ /** Return first Value for property or null if no Value for that property. */ Value getValue(URI property); /** Replace (self,p,?x) with (self,p,newValue). */ void setValue(URI property, Value newValue); /** Assert (self,p,newValue). */ void addValue(URI property, Value newValue); // /** Assert (self,p,target). */ // void addLink(URI property,IGPO target); /** Return the {@link IGPO} modeling the link iff it exists. */ IGPO getLink(URI property, IGPO target); /** Remove (self,p,oldValue) if found. */ void removeValue(URI property, Value oldValue); /** Remove all (self,p,?). */ void removeValues(URI property); /** All (self,?p,?o). */ Set<Statement> getStatements(); /** All ?y where (self,p,?y). */ Set<Value> getValues(URI property); /** All ?y where (?y,?p,self). */ Set<IGPO> getLinksIn(); /** All ?y where (?y,p,self). */ ILinkSet getLinksIn(URI property); /** All ?y where (self,?p,?y) and ?y is Resource. */ Set<IGPO> getLinksOut(); /** All ?y where (self,p,?y) and ?y is Resource. */ ILinkSet getLinksOut(URI property); /** Exists (?x,linkSet.property,self). */ boolean isMemberOf(ILinkSet linkSet); /** Exists (self,p,?y). */ boolean isBound(URI property); /** * Return a map giving the range count for each reverse link property. * <pre> * SELECT ?p, COUNT(*) WHERE { ?o ?p <s> } GROUP BY ?p * </pre> */ Map<URI,Long> getReverseLinkProperties(); /** * Removes the persistent object. Any links to this generic object are also * removed. Any link sets collected by this generic object are removed. * <p> * * While this clears all link sets held by the generic object, the members * of those link sets are NOT explicitly removed since they may participate * in other associations. * <p> * * The {@link IGPO} interface may no longer be used for this object if this * operation is successful. * <p> */ void remove(); /** * Returns an transient object that wraps the same persistent object but * exposes the behavior identified by the identified interface. The * interface effectively names the behavior that will be wrapped around the * persistent data. If the current object already implements the desired * interface, then it is simply returned. If a suitable {@link IGenericSkin} * has already been minted for this generic object, then it is simply * returned. Otherwise an implementation class for the interface MUST have * been registered with the runtime and MUST implement a constructor * accepting a single {@link IGenericSkin} argument. * <p> * * The life cycle of a skin object returned by this method MUST be no less * than the in-memory life cycle of the generic object for which the skin * was minted. This constraint makes it possible to have transient yet * expensive initialization, such as caches, on skin objects. * <p> * * @exception UnsupportedOperationException * If the runtime is unable to identify an implementation * class for the specified interface. * * @return An object that wraps the same persistent data but implements the * desired interface. * * @see IGenericSkin * @see GenericSkinRegistry */ IGenericSkin asClass(Class theClassOrInterface); /** * Force the full materialization of the {@link IGPO}. * * @return This {@link IGPO}. */ IGPO materialize(); /** * @return a pretty printed representation of the GPO */ String pp(); /** * FIXME: this method will be moved to an as yet unnamed derived class * that will become the superclass for alchemist generated subclasses. */ IGPO getType(); }