/* * Created on Mar 16, 2005 */ package edu.mit.simile.fresnel.format; import java.util.HashSet; import java.util.Set; import org.openrdf.model.Literal; import org.openrdf.model.Resource; import org.openrdf.model.Statement; import org.openrdf.model.URI; 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 fr.inria.jfresnel.fsl.FSLPath; import edu.mit.simile.fresnel.FresnelCoreTypes; import edu.mit.simile.fresnel.FresnelResource; import edu.mit.simile.fresnel.configuration.Configuration; import edu.mit.simile.fresnel.purpose.Purpose; import edu.mit.simile.fresnel.purpose.PurposeSet; import edu.mit.simile.fresnel.selection.AllPropertiesSelector; import edu.mit.simile.fresnel.selection.AllPropertiesSet; import edu.mit.simile.fresnel.selection.FSESelector; import edu.mit.simile.fresnel.selection.ISelector; import edu.mit.simile.fresnel.selection.ParsingException; import edu.mit.simile.fresnel.selection.PropertySelector; import edu.mit.simile.fresnel.selection.SPARQLSelector; import edu.mit.simile.fresnel.selection.UnresolvableException; import edu.mit.simile.vocabularies.FresnelCore; /** * Represents a fresnel:Format. * * @author ryanlee */ public class Format extends FresnelResource{ /** * Resource defined in the schema. */ protected static Resource _schemaResource = FresnelCore.Format; /** * Context for determining FSL first location step type. */ protected final static short _fslContext = FSLPath.NODE_STEP; /** * Resource identifying this format. */ private Resource _identifier; /** * Match the domain to a model to choose properties for formatting. */ private Set<ISelector> _domains; /** * Specify the purposes of the format. */ private PurposeSet _purposes; /** * The property label of the property's format */ private PropertyLabel _label; /** * The value type of the property's format */ private PropertyValue _value; /** * The styling for a resource */ private Set<Style>_resourceStyle; /** * The styling for a property */ private Set<Style> _propertyStyle; /** * The styling for a label */ private Set<Style> _labelStyle; /** * The styling for a value */ private Set<Style> _valueStyle; /** * The formatting for a resource */ private Set<FormatDescription> _resourceFormat; /** * The formatting for a property */ private Set<FormatDescription> _propertyFormat; /** * The formatting for a label */ private Set<FormatDescription> _labelFormat; /** * The formatting for a value */ private Set<FormatDescription> _valueFormat; /** * Constructor with identifying resource * * @param id A <code>Resource</code> */ public Format(Resource id) { setIdentifier(id); this._domains = new HashSet<ISelector>(); this._purposes = new PurposeSet(); this._label = new PropertyLabel(); this._value = new PropertyValue(); this._resourceStyle = new HashSet<Style>(); this._propertyStyle = new HashSet<Style>(); this._labelStyle = new HashSet<Style>(); this._valueStyle = new HashSet<Style>(); this._resourceFormat = new HashSet<FormatDescription>(); this._propertyFormat = new HashSet<FormatDescription>(); this._labelFormat = new HashSet<FormatDescription>(); this._valueFormat = new HashSet<FormatDescription>(); } /** * Retrieves the identifying resource * * @return A <code>Resource</code> identifier */ public Resource getIdentifier() { return this._identifier; } /** * Returns the format domains. * * @return A <code>DomainSet</code> */ public Set<ISelector> getDomainSet() { return this._domains; } /** * Returns the purposes of the format. * * @return A <code>PurposeSet</code> */ public PurposeSet getPurposes() { return this._purposes; } /** * Retrieves the label object * * @return A <code>PropertyLabel</code> */ public PropertyLabel getLabel() { return this._label; } /** * Retrieves the value type object * * @return A <code>PropertyValue</code> */ public PropertyValue getValueType() { return this._value; } /** * Retrieves the style values associated with a resource * * @return A <code>StyleSet</code> */ public Set<Style> getResourceStyle() { return this._resourceStyle; } /** * Retrieves the style values associated with a property * * @return A <code>StyleSet</code> */ public Set<Style> getPropertyStyle() { return this._propertyStyle; } /** * Retrieves the style values associated with a label * * @return A <code>StyleSet</code> */ public Set<Style> getLabelStyle() { return this._labelStyle; } /** * Retrieves the style values associated with a value * * @return A <code>StyleSet</code> */ public Set<Style> getValueStyle() { return this._valueStyle; } /** * Retrieves the format values associated with a resource * * @return A <code>FormatDescriptionSet</code> */ public Set<FormatDescription> getResourceFormat() { return this._resourceFormat; } /** * Retrieves the format values associated with a property * * @return A <code>FormatDescriptionSet</code> */ public Set<FormatDescription> getPropertyFormat() { return this._propertyFormat; } /** * Retrieves the format values associated with a label * * @return A <code>FormatDescriptionSet</code> */ public Set<FormatDescription> getLabelFormat() { return this._labelFormat; } /** * Retrieves the format values associated with a value * * @return A <code>FormatDescriptionSet</code> */ public Set<FormatDescription> getValueFormat() { return this._valueFormat; } /** * Sets the resource identifying this format. * * @param identifier A unique <code>Resource</code> */ protected void setIdentifier(Resource identifier) { this._identifier = identifier; } /** * Adds an applicable domain to the existing set of domains * * @param domain An appropriate <code>ISelector</code> * @return True if the addition succeeded, false if not */ public boolean addDomain(ISelector domain) { return this._domains.add(domain); } /** * Adds a purpose to the existing set of purposes. * * @param purpose A <code>Purpose</code> * @return True if the addition succeeded, false if not */ public boolean addPurpose(Purpose purpose) { return this._purposes.addPurpose(purpose); } /** * Sets the label for the format * * @param label A <code>PropertyLabel</code> */ protected void setLabel(PropertyLabel label) { this._label = label; } /** * Sets the value type for the format * * @param value A <codde>PropertyValue</code> */ protected void setValueType(PropertyValue value) { this._value = value; } /** * Sets the styling for a resource * * @param style A <code>StyleSet</code> */ protected void setResourceStyle(Set<Style> style) { this._resourceStyle = style; } /** * Sets the styling for a property * * @param style A <code>StyleSet</code> */ protected void setPropertyStyle(Set<Style> style) { this._propertyStyle = style; } /** * Sets the styling for a label * * @param style A <code>StyleSet</code> */ protected void setLabelStyle(Set<Style> style) { this._labelStyle = style; } /** * Sets the styling for a value * * @param style A <code>StyleSet</code> */ protected void setValueStyle(Set<Style> style) { this._valueStyle = style; } /** * Adds a styling for a resource * * @param style A <code>Style</code> */ protected void addResourceStyle(Style style) { this._resourceStyle.add(style); } /** * Adds a styling for a property * * @param style A <code>Style</code> */ protected void addPropertyStyle(Style style) { this._propertyStyle.add(style); } /** * Adds a styling for a label * * @param style A <code>Style</code> */ protected void addLabelStyle(Style style) { this._labelStyle.add(style); } /** * Adds a styling for a value * * @param style A <code>Style</code> */ protected void addValueStyle(Style style) { this._valueStyle.add(style); } /** * Sets the formatting for a resource * * @param fd A <code>FormatDescriptionSet</code> */ protected void setResourceFormat(Set<FormatDescription> fd) { this._resourceFormat = fd; } /** * Sets the formatting for a property * * @param fd A <code>FormatDescriptionSet</code> */ protected void setPropertyFormat(Set<FormatDescription> fd) { this._propertyFormat = fd; } /** * Sets the formatting for a label * * @param fd A <code>FormatDescriptionSet</code> */ protected void setLabelFormat(Set<FormatDescription> fd) { this._labelFormat = fd; } /** * Sets the formatting for a value * * @param fd A <code>FormatDescriptionSet</code> */ protected void setValueFormat(Set<FormatDescription> fd) { this._valueFormat = fd; } /** * Adds a formatting for a resource * * @param format A <code>FormatDescription</code> */ protected void addResourceFormat(FormatDescription format) { this._resourceFormat.add(format); } /** * Adds a formatting for a property * * @param format A <code>FormatDescription</code> */ protected void addPropertyFormat(FormatDescription format) { this._propertyFormat.add(format); } /** * Adds a formatting for a label * * @param format A <code>FormatDescription</code> */ protected void addLabelFormat(FormatDescription format) { this._labelFormat.add(format); } /** * Adds a formatting for a value * * @param format A <code>FormatDescription</code> */ protected void addValueFormat(FormatDescription format) { this._valueFormat.add(format); } /** * Check if this style has a particular purpose. * * @param check A <code>Purpose</code> to check against * @return A <code>boolean</code> indicator */ public boolean hasPurpose(Purpose check) { return this._purposes.contains(check); } /** * Parses a resource into a valid fresnel:Format object. * * @param in The <code>Repository</code> the configuration is derived from * @param selected The fresnel:Format <code>Resource</code> * @param conf The <code>Configuration</code> to add to * @return A new <code>Format</code> * @throws UnresolvableException When the wrong count for a predicate is present * @throws ParsingException When any other syntax error occurs */ public static Format parse(Repository in, Resource selected, Configuration conf) throws UnresolvableException, ParsingException { Format out = new Format(selected); try { // Parse domain parseDomain(out, in, selected, conf); RepositoryConnection conn = in.getConnection(); // Set of purposes RepositoryResult<Statement> purposesI = conn.getStatements(selected, FresnelCore.purpose, (Value) null, false); try { while (purposesI.hasNext()) { Value purposeNode = purposesI.next().getObject(); if (purposeNode instanceof Resource) { Resource purposeRes = (Resource) purposeNode; out.addPurpose(new Purpose(purposeRes)); } else { throw new ParsingException(purposeNode.toString() + "could not be used as a :Purpose"); } } } finally { purposesI.close(); } // label RepositoryResult<Statement> labelI = conn.getStatements(selected, FresnelCore.label, (Value) null, false); try { if (labelI.hasNext()) { Statement labelS = labelI.next(); if (labelI.hasNext()) throw new ParsingException("Too many fresnel:label statements; only one allowed: " + selected); Value labelObj = labelS.getObject(); out.setLabel(PropertyLabel.parse(labelObj)); } } finally { labelI.close(); } // value RepositoryResult<Statement> valueI = conn.getStatements(selected, FresnelCore.value, (Value) null, false); try { if (valueI.hasNext()) { Statement valueS = valueI.next(); if (valueI.hasNext()) throw new ParsingException("Too many fresnel:value statements; only one allowed: " + selected); Value valueObj = valueS.getObject(); out.setValueType(PropertyValue.parse(valueObj)); } } finally { valueI.close(); } // property style RepositoryResult<Statement> propertyStyleI = conn.getStatements(selected, FresnelCore.propertyStyle, (Value) null, false); while (propertyStyleI.hasNext()) { Statement propertyStyleS = propertyStyleI.next(); Value styleObj = propertyStyleS.getObject(); out.addPropertyStyle(Style.parse(styleObj)); } propertyStyleI.close(); // label style RepositoryResult<Statement> labelStyleI = conn.getStatements(selected, FresnelCore.labelStyle, (Value) null, false); while (labelStyleI.hasNext()) { Statement labelStyleS = labelStyleI.next(); Value styleObj = labelStyleS.getObject(); out.addLabelStyle(Style.parse(styleObj)); } labelStyleI.close(); // value style RepositoryResult<Statement> valueStyleI = conn.getStatements(selected, FresnelCore.valueStyle, (Value) null, false); while (valueStyleI.hasNext()) { Statement valueStyleS = valueStyleI.next(); Value styleObj = valueStyleS.getObject(); out.addValueStyle(Style.parse(styleObj)); } valueStyleI.close(); // property format RepositoryResult<Statement> propertyFormatI = conn.getStatements(selected, FresnelCore.propertyFormat, (Value) null, false); while (propertyFormatI.hasNext()) { Statement propertyFormatS = propertyFormatI.next(); Resource formatObj = (Resource) propertyFormatS.getObject(); out.addPropertyFormat(FormatDescription.parse(in, formatObj)); } propertyFormatI.close(); // label format RepositoryResult<Statement> labelFormatI = conn.getStatements(selected, FresnelCore.labelFormat, (Value) null, false); while (labelFormatI.hasNext()) { Statement labelFormatS = labelFormatI.next(); Resource formatObj = (Resource) labelFormatS.getObject(); out.addLabelFormat(FormatDescription.parse(in, formatObj)); } labelFormatI.close(); // value format RepositoryResult<Statement> valueFormatI = conn.getStatements(selected, FresnelCore.valueFormat, (Value) null, false); while (valueFormatI.hasNext()) { Statement valueFormatS = valueFormatI.next(); Resource formatObj = (Resource) valueFormatS.getObject(); out.addValueFormat(FormatDescription.parse(in, formatObj)); } valueFormatI.close(); conn.close(); } catch (RepositoryException e) { throw new UnresolvableException("Problem connecting to repository: " + e.getLocalizedMessage()); } return out; } /** * Parse out domain information and add to the Format. * * @param out The <code>Format</code> to modify * @param in The <code>Repository</code> containing configuration information * @param selected The <code>Resource</code> identifying the style * @param conf The <code>Configuration</code> parsing this format */ protected static void parseDomain(Format out, Repository in, Resource selected, Configuration conf) throws RepositoryException { RepositoryConnection conn = in.getConnection(); RepositoryResult<Statement> domainsI = conn.getStatements(selected, FresnelCore.propertyFormatDomain, (Value) null, false); while (domainsI.hasNext()) { ISelector domain = null; Value domainNode = domainsI.next().getObject(); if (domainNode instanceof Resource) { if (((Resource) domainNode).equals(AllPropertiesSet.getSchemaResource())) { domain = new AllPropertiesSelector(); } else { // This is a property selector domain = new PropertySelector((URI) domainNode); } } else if (domainNode instanceof Literal) { Literal domainL = (Literal) domainNode; // TODO: catch bad expressions? throw exceptions? if (domainL.getDatatype().equals(FresnelCoreTypes.fslSelector)) { domain = new FSESelector(domainL.getLabel(), _fslContext, conf.getNamespaceMap()); } else if (domainL.getDatatype().equals(FresnelCoreTypes.fslSelector)) { domain = new SPARQLSelector(domainL.getLabel(), conf.getNamespaces()); } } out.addDomain(domain); } domainsI.close(); conn.close(); } /** * @see java.lang.Object#toString() */ public String toString() { String state = " [Format " + super.toString() + "]\n"; state += " " + this._identifier + "\n"; state += "\n Domain(s):\n"; state += this._domains; state += "\n Purpose(s):\n"; state += this._purposes; state += "\n Property Type:\n"; if (null != this._label) state += this._label; if (null != this._value) state += this._value; state += "\n Styling(s):\n"; if (0 != this._resourceStyle.size()) state += this._resourceStyle + " [resource]\n"; if (0 != this._propertyStyle.size()) state += this._propertyStyle + " [property]\n"; if (0 != this._labelStyle.size()) state += this._labelStyle + " [label]\n"; if (0 != this._valueStyle.size()) state += this._valueStyle + " [value]\n"; state += "\n Content format(s):\n"; if (0 != this._resourceFormat.size()) state += this._resourceFormat + " [resource]\n"; if (0 != this._propertyFormat.size()) state += this._propertyFormat + " [property]\n"; if (0 != this._labelFormat.size()) state += this._labelFormat + " [label]\n"; if (0 != this._valueFormat.size()) state += this._valueFormat + " [value]\n"; state += " ====== [end format]"; return state; } }