/*
* 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.stanbol.entityhub.core.impl;
import java.util.Date;
import java.util.Iterator;
import org.apache.stanbol.entityhub.servicesapi.model.Entity;
import org.apache.stanbol.entityhub.servicesapi.model.ManagedEntityState;
import org.apache.stanbol.entityhub.servicesapi.model.Reference;
import org.apache.stanbol.entityhub.servicesapi.model.Representation;
import org.apache.stanbol.entityhub.servicesapi.model.Text;
import org.apache.stanbol.entityhub.servicesapi.model.rdf.RdfResourceEnum;
import org.apache.stanbol.entityhub.servicesapi.util.ModelUtils;
import org.apache.stanbol.entityhub.servicesapi.util.ToStringIterator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* wrapper over an Entity that allows API based read/write access
* to metadata typically needed by the Entityhub Implementation.
* @author Rupert Westenthaler
*
*/
public class ManagedEntity extends EntityWrapper {
private static final Logger log = LoggerFactory.getLogger(ManagedEntity.class);
/**
* The default state for new symbols if not defined otherwise
*/
public static final ManagedEntityState DEFAULT_SYMBOL_STATE = ManagedEntityState.proposed;
/**
* The property to be used for the symbol label
*/
public static final String LABEL = RdfResourceEnum.label.getUri();
/**
* The property to be used for the symbol description
*/
public static final String DESCRIPTION = RdfResourceEnum.description.getUri();
/**
* The property to be used for the symbol state
*/
public static final String STATE = RdfResourceEnum.hasState.getUri();
/**
* The property used for linking to successors
*/
public static final String SUCCESSOR = RdfResourceEnum.successor.getUri();
/**
* The property used for linking to predecessors
*/
public static final String PREDECESSOR = RdfResourceEnum.predecessor.getUri();
private String defaultLanguage = null;
private static final String[] ALT_LABEL_LANGUAGES = new String[]{null,"en"};
/**
* Holds a reference to the {@link Entity#getMetadata()} of the
* wrapped entity
*/
private final Representation metadata;
/**
* Creates a wrapper over an Entity that allows API based read/write access
* to metadata typically needed by the Entityhub Implementation.
* @param entity the wrapped entity
* @throws IllegalArgumentException if the parsed Entity is <code>null</code>
*/
public ManagedEntity(Entity entity) throws IllegalArgumentException {
this(entity,true);
}
/**
* Internally used to allow parsing <code>validate == false</code> in cases
* the validation is not necessary.
* @param entity
* @param validate
*/
private ManagedEntity(Entity entity,boolean validate){
super(entity);
// if(entity == null){
// throw new IllegalArgumentException("The parsed Entity MUST NOT be NULL");
// }
if(validate && !canWrap(entity)){
throw new IllegalArgumentException(String.format(
"Unable to wrap Entity %s",entity));
}
this.metadata = wrappedEntity.getMetadata();
}
/**
* Checks if the parsed Entity can be wrapped as a locally managed entity.
* This checks currently of a {@link ManagedEntityState} is defined by the
* metadata.
* @param entity the entity to check
* @return the state
*/
public static boolean canWrap(Entity entity) {
//check the metadata for
//if the entity is managed locally
//if the entity has an state
Reference stateUri = entity.getMetadata().getFirstReference(STATE);
if(stateUri == null ||
!ManagedEntityState.isState(stateUri.getReference())){
return false;
}
//check the about
String entityId = ModelUtils.getAboutRepresentation(entity.getMetadata());
if(entityId == null || !entityId.equals(entity.getRepresentation().getId())){
return false;
}
return true;
}
/**
* Sets the parsed default state to the metadata if no other one is already
* present and that wraps the entity as locally managed entity.
* @param entity the entity
* @param defaultState the default state used if no one is yet defined for
* this entity
* @return the wrapped entity
*/
public static ManagedEntity init(Entity entity, ManagedEntityState defaultState){
Reference stateUri = entity.getMetadata().getFirstReference(STATE);
if(stateUri == null ||
!ManagedEntityState.isState(stateUri.getReference())){
entity.getMetadata().setReference(STATE, defaultState.getUri());
}
String entityId = ModelUtils.getAboutRepresentation(entity.getMetadata());
if(entityId == null){
entity.getMetadata().setReference(
RdfResourceEnum.aboutRepresentation.getUri(),
entity.getRepresentation().getId());
} else if(!entityId.equals(entity.getRepresentation().getId())){
//the metadata are about a different Entity ->
throw new IllegalArgumentException(String.format(
"The Metadata of the parsed Entity are not about the Entity ("+
"entity: %s | metadataId: %s | metadataAbout: %s)",
entity.getRepresentation().getId(),entity.getMetadata().getId(),
entityId));
}//else the ID value is OK
return new ManagedEntity(entity,false);
}
/**
* Adds a description in the default language to the Symbol
* @param description the description
*/
public final void addDescription(String description) {
metadata.addNaturalText(DESCRIPTION, description,defaultLanguage);
}
/**
* Adds a description in the parsed language to the Symbol
* @param description the description
* @param lanugage the language. <code>null</code> indicates to use no language tag
*/
public final void addDescription(String description, String lanugage) {
metadata.addNaturalText(DESCRIPTION, description,lanugage);
}
/**
* Adds the symbol with the parsed ID as a predecessor
* @param predecessor the id of the predecessors
*/
public final void addPredecessor(String predecessor) {
metadata.addReference(PREDECESSOR, predecessor);
}
/**
* Adds the symbol with the parsed ID as a successor
* @param successor the id of the successor
*/
public final void addSuccessor(String successor) {
metadata.addReference(SUCCESSOR, successor);
}
/**
* Getter for the descriptions of this symbol in the default language.
* @return The descriptions or an empty collection.
*/
public final Iterator<Text> getDescriptions() {
return metadata.getText(DESCRIPTION);
}
/**
* Getter for the short description as defined for the parsed language.
* @param lang The language. Parse <code>null</code> for values without language tags
* @return The description or <code>null</code> if no description is defined
* for the parsed language.
*/
public final Iterator<Text> getDescriptions(String lang) {
return metadata.get(DESCRIPTION, lang);
}
/**
* The label of this Symbol in the default language
* @return the label
*/
public final String getLabel() {
String label = getLabel(defaultLanguage);
if(label == null){ //no label for the default language
//search labels in other languages
Text altLabel = metadata.getFirst(LABEL, ALT_LABEL_LANGUAGES);
if(altLabel == null){
Iterator<Text> labels = metadata.getText(LABEL);
if(labels.hasNext()){
altLabel = labels.next();
}
}
return altLabel!=null?altLabel.getText():null;
} else {
return label;
}
}
/**
* The preferred label of this Symbol in the given language or
* <code>null</code> if no label for this language is defined
* TODO: how to handle internationalisation.
* @param lang the language
* @return The preferred label of this Symbol in the given language or
* <code>null</code> if no label for this language is defined
*/
public final String getLabel(String lang) {
Text label = metadata.getFirst(LABEL, lang);
return label!=null?label.getText():null;
}
/**
* Getter for the ID's of the symbols defined as predecessors of this one.
* @return The id's of the symbols defined as predecessors of this one or an
* empty list if there are no predecessors are defined.
*/
public final Iterator<String> getPredecessors() {
return new ToStringIterator(metadata.get(PREDECESSOR));
}
/**
* Getter for the state of this symbol
* @return the state
*/
public final ManagedEntityState getState() {
Reference stateUri = metadata.getFirstReference(STATE);
if(stateUri != null){
if(ManagedEntityState.isState(stateUri.getReference())){
return ManagedEntityState.getState(stateUri.getReference());
} else {
log.warn("Value {} for field {} is not a valied SymbolState! -> return null",
stateUri,STATE);
return null;
}
} else {
return null;
}
}
/**
* Getter for the ID's of the symbols defined as successors of this one.
* @return The id's of the symbols defined as successors of this one or an
* empty list if there are no successors are defined.
*/
public final Iterator<String> getSuccessors() {
return new ToStringIterator(metadata.get(SUCCESSOR));
}
/**
* Returns if this Symbols does have any predecessors
* @return Returns <code>true</code> if predecessors are defined for this
* symbol; otherwise <code>false</code>.
*/
public final boolean isPredecessors() {
return getPredecessors().hasNext();
}
/**
* Returns if this Symbols does have any successors
* @return Returns <code>true</code> if successors are defined for this
* symbol; otherwise <code>false</code>.
*/
public final boolean isSuccessor() {
return getSuccessors().hasNext();
}
/**
* Removes the description in the default language from the Symbol
* @param description the description to remove
*/
public final void removeDescription(String description) {
metadata.removeNaturalText(DESCRIPTION,description,defaultLanguage);
}
/**
* Removes the description in the parsed language from the Symbol
* @param description the description to remove
* @param language the language. <code>null</code> indicates to use no language tag
*/
public final void removeDescription(String description, String language) {
metadata.removeNaturalText(DESCRIPTION,description,language);
}
/**
* Removes the symbol with the parsed ID as a predecessor
* @param predecessor the id of the predecessor to remove
*/
public final void removePredecessor(String predecessor) {
metadata.removeReference(PREDECESSOR, predecessor);
}
/**
* Removes the symbol with the parsed ID as a successor
* @param successor the id of the successor to remove
*/
public final void removeSuccessor(String successor) {
metadata.removeReference(SUCCESSOR, successor);
}
/**
* Setter for the Label in the default Language
* @param label
*/
public final void setLabel(String label) {
metadata.setNaturalText(LABEL, label, defaultLanguage);
}
/**
* Setter for a label of a specific language
* @param label the label
* @param language the language. <code>null</code> indicates to use no language tag
*/
public final void setLabel(String label, String language) {
metadata.setNaturalText(LABEL, label, language);
}
/**
* Setter for the state of the Symbol
* @param state the new state
* @throws IllegalArgumentException if the parsed state is <code>null</code>
*/
public final void setState(ManagedEntityState state) throws IllegalArgumentException {
if(state != null){
metadata.setReference(STATE, state.getUri());
} else {
throw new IllegalArgumentException("SymbolState can not be set to NULL!");
}
}
/**
* Getter for the default language used for {@link #getLabel()}
* @return the preferred language used for {@link #getLabel()}
*/
public final String getDefaultLanguage() {
return defaultLanguage;
}
/**
* Setter for the default language used for {@link #getLabel()} (
* <code>null</code> is supported)
* @param defaultLanguage the preferred language used for {@link #getLabel()}
*/
public final void setDefaultLanguage(String defaultLanguage) {
this.defaultLanguage = defaultLanguage;
}
// /**
// * Setter for the ID of the Metadata for this managed entity.
// * @param id the id of the metadata of this entity
// */
// public final void setMetadataId(String id){
// wrappedEntity.getRepresentation().setReference(
// RdfResourceEnum.hasMetadata.getUri(), id);
// }
// /**
// * Getter for the ID of the Metadata for this managed entity.
// * @return the id of the metadata of entity
// */
// public final String getMetadataId(){
// Reference ref = wrappedEntity.getRepresentation().getFirstReference(
// RdfResourceEnum.hasMetadata.getUri());
// return ref == null ? null : ref.getReference();
// }
}