package edu.mit.simile.fresnel.facets; import java.util.Iterator; import java.util.Vector; import org.openrdf.model.Resource; import org.openrdf.model.Statement; import org.openrdf.model.Value; import org.openrdf.repository.Repository; import org.openrdf.repository.RepositoryConnection; import org.openrdf.repository.RepositoryException; import org.openrdf.repository.RepositoryResult; import edu.mit.simile.fresnel.selection.ParsingException; import edu.mit.simile.fresnel.selection.UnresolvableException; import edu.mit.simile.fresnel.util.RDFList; import edu.mit.simile.fresnel.util.WrappedVector; import edu.mit.simile.vocabularies.Facets; /** * Container for facets, reflecting the fresnel:FacetSet member of the fresnel faceting extension * vocabulary. * * @author ryanlee */ public class FacetSet extends WrappedVector<Facet> { /** * Set of types these facets can be used with. */ protected TypeSet _forTypes; /** * Resource identifying this FacetSet. */ protected Resource _identifier; /** * Set of facets to hide. */ protected Vector<Facet> _hides; /** * Resource defined in the schema. */ protected static final Resource _schemaResource = Facets.FacetSet; /** * Constructor for initializing wrapped vector. */ public FacetSet() { super(); this._hides = new Vector<Facet>(); } /** * Constructor based on the resource identifying the facet set. * * @param id A <code>Resource</code> */ public FacetSet(Resource id) { this(); this._identifier = id; } /** * Retrieves the resource identifying this facet set. * * @return A <code>Resource</code> */ public Resource getIdentifier() { return this._identifier; } /** * Retrieves an iterator through the set of types this facet set can be used for. * * @return A <code>TypeIterator</code> */ public Iterator<Resource> getForTypes() { return this._forTypes.iterator(); } /** * Sets the set of types this facet set can be use for. * * @param types A <code>TypeSet</code> */ public void setForTypes(TypeSet types) { this._forTypes = types; } /** * Returns a FacetIterator (instead of a normal iterator) through this set of facets. * * @return A <code>FacetIterator</code> */ public Iterator<Facet> facetIterator() { return this._base.iterator(); } /** * Returns a FacetIterator through the hidden facets. * * @return A <code>FacetIterator</code> */ public Iterator<Facet> hideIterator() { return this._hides.iterator(); } /** * Check if this facet set's type set is actually intended to be used for all types * and not just a specific set. * * @return True if for all types, false otherwise. */ public boolean isForAll() { return this._forTypes.isForAll(); } /** * Adds a facet to the existing set. * * @param facet A <code>Facet</code> * @return Success or failure */ public boolean addFacet(Facet facet) { return this._base.add(facet); } /** * Adds a facet to the hidden facet list. * * @param facet A <code>Facet</code> * @return Sucess or failure */ public boolean addHide(Facet facet) { return this._hides.add(facet); } /** * Removes a facet from the existing set. * * @param facet A <code>Facet</code> * @return Success or failure */ public boolean removeFacet(Facet facet) { return this._base.remove(facet); } /** * Removes a hidden facet from the existing set. * * @param facet A <code>Facet</code> * @return Success or failure */ public boolean removeHide(Facet facet) { return this._hides.remove(facet); } /** * Add all elements from a facet set into this one. * * @param arg0 A <code>FacetSet</code> * @return Success or failure */ public boolean addFacetSet(FacetSet arg0) { return (this._base.addAll(arg0._base) && this._hides.addAll(arg0._hides)); } /** * Parses a configuration graph for facet set information on the given resource. * * @param source Configuration source <code>Repository</code> * @param focus <code>Resource</code> to parse * @return A <code>FacetSet</code> */ public static FacetSet parse(Repository source, Resource focus) throws UnresolvableException, ParsingException { FacetSet out = new FacetSet(focus); try { RepositoryConnection conn = source.getConnection(); RepositoryResult<Statement> facetI = conn.getStatements(focus, Facets.facets, (Value) null, false); if (facetI.hasNext()) { Statement facetStmt = (Statement) facetI.next(); Value facetsNode = facetStmt.getObject(); if (facetI.hasNext()) throw new UnresolvableException("More than one :facets value available"); if (facetsNode instanceof Resource && RDFList.isRDFList(source, (Resource) facetsNode)) { RDFList facetRDFList = new RDFList(source, (Resource) facetsNode); if (facetRDFList.isValid()) { for (Iterator listI = facetRDFList.iterator(); listI.hasNext(); ) { Resource facetNode = (Resource) listI.next(); Facet facet = new Facet(facetNode); out.addFacet(facet); } } else { throw new ParsingException(facetsNode.toString() + "is not a valid rdf:List"); } } } facetI.close(); RepositoryResult<Statement> hidesI = conn.getStatements(focus, Facets.hides, (Value) null, false); if (hidesI.hasNext()) { Statement facetStmt = hidesI.next(); Value facetsNode = facetStmt.getObject(); if (hidesI.hasNext()) throw new UnresolvableException("More than one :hides value available"); if (facetsNode instanceof Resource && RDFList.isRDFList(source, (Resource) facetsNode)) { RDFList facetRDFList = new RDFList(source, (Resource) facetsNode); if (facetRDFList.isValid()) { for (Iterator listI = facetRDFList.iterator(); listI.hasNext(); ) { Resource facetNode = (Resource) listI.next(); Facet facet = new Facet(facetNode); out.addHide(facet); } } else { throw new ParsingException(facetsNode.toString() + "is not a valid rdf:List"); } } } hidesI.close(); conn.close(); } catch (RepositoryException e) { throw new UnresolvableException("Problem connecting to repository: " + e.getLocalizedMessage()); } TypeSet forTypes = TypeSet.parse(source, focus); out.setForTypes(forTypes); return out; } /** * @see java.lang.Object#toString() */ public String toString() { String state = "[FacetSet " + super.toString() + "]\n"; state += " " + this._forTypes.toString(); Iterator<Facet> it = this.facetIterator(); while (it.hasNext()) { Facet select = it.next(); state += " [Facet " + select.getIdentifier() + "]\n"; } it = this.hideIterator(); while (it.hasNext()) { Facet select = it.next(); state += " [Hide facet " + select.getIdentifier() + "]\n"; } return state; } }