/**
* $Id: EntityBrokerImpl.java 123125 2013-04-23 01:03:34Z azeckoski@unicon.net $
* $URL: https://source.sakaiproject.org/svn/entitybroker/trunk/impl/src/java/org/sakaiproject/entitybroker/impl/EntityBrokerImpl.java $
* EntityBrokerImpl.java - entity-broker - Apr 6, 2008 9:03:03 AM - azeckoski
**************************************************************************
* Copyright (c) 2007, 2008, 2009 The Sakai Foundation
*
* Licensed under the Educational Community 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.opensource.org/licenses/ECL-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.sakaiproject.entitybroker.impl;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.sakaiproject.entitybroker.EntityBroker;
import org.sakaiproject.entitybroker.EntityReference;
import org.sakaiproject.entitybroker.EntityView;
import org.sakaiproject.entitybroker.entityprovider.EntityProviderManager;
import org.sakaiproject.entitybroker.entityprovider.capabilities.ActionsExecutable;
import org.sakaiproject.entitybroker.entityprovider.extension.ActionReturn;
import org.sakaiproject.entitybroker.entityprovider.extension.BrowseEntity;
import org.sakaiproject.entitybroker.entityprovider.extension.EntityData;
import org.sakaiproject.entitybroker.entityprovider.extension.PropertiesProvider;
import org.sakaiproject.entitybroker.entityprovider.extension.QuerySearch;
import org.sakaiproject.entitybroker.entityprovider.extension.RequestStorageWrite;
import org.sakaiproject.entitybroker.entityprovider.extension.SearchContent;
import org.sakaiproject.entitybroker.entityprovider.extension.SearchProvider;
import org.sakaiproject.entitybroker.entityprovider.extension.SearchResults;
import org.sakaiproject.entitybroker.entityprovider.extension.TagSearchService;
import org.sakaiproject.entitybroker.entityprovider.search.Search;
import org.sakaiproject.entitybroker.providers.ExternalIntegrationProvider;
import org.sakaiproject.entitybroker.util.EntityResponse;
/**
* The default implementation of the EntityBroker interface
*
* @author Aaron Zeckoski (aaron@caret.cam.ac.uk)
* @author Antranig Basman (antranig@caret.cam.ac.uk)
*/
public class EntityBrokerImpl implements EntityBroker, PropertiesProvider {
public void init() {
// setup the external providers
if (externalIntegrationProvider != null) {
SearchProvider searchProvider = externalIntegrationProvider.findService(SearchProvider.class);
if (searchProvider != null) {
this.searchProvider = searchProvider;
}
}
}
/**
* Empty constructor
*/
protected EntityBrokerImpl() { }
/**
* Minimal constructor
*/
public EntityBrokerImpl(EntityProviderManager entityProviderManager,
EntityBrokerManagerImpl entityBrokerManager,
RequestStorageWrite requestStorageWrite) {
super();
this.entityProviderManager = entityProviderManager;
this.entityBrokerManager = entityBrokerManager;
this.requestStorage = requestStorageWrite;
}
/**
* Full constructor with optional pieces
*/
public EntityBrokerImpl(EntityProviderManager entityProviderManager,
EntityBrokerManagerImpl entityBrokerManager,
RequestStorageWrite requestStorageWrite,
PropertiesProvider propertiesProvider,
TagSearchService tagSearchService) {
super();
this.entityProviderManager = entityProviderManager;
this.entityBrokerManager = entityBrokerManager;
this.requestStorage = requestStorageWrite;
this.propertiesProvider = propertiesProvider;
this.tagSearchService = tagSearchService;
}
private EntityProviderManager entityProviderManager;
public void setEntityProviderManager(EntityProviderManager entityProviderManager) {
this.entityProviderManager = entityProviderManager;
}
private EntityBrokerManagerImpl entityBrokerManager;
public void setEntityBrokerManager(EntityBrokerManagerImpl entityBrokerManager) {
this.entityBrokerManager = entityBrokerManager;
}
private RequestStorageWrite requestStorage;
public void setRequestStorage(RequestStorageWrite requestStorage) {
this.requestStorage = requestStorage;
}
private ExternalIntegrationProvider externalIntegrationProvider;
public void setExternalIntegrationProvider(
ExternalIntegrationProvider externalIntegrationProvider) {
this.externalIntegrationProvider = externalIntegrationProvider;
}
// OPTIONAL Data Storage providers
private PropertiesProvider propertiesProvider;
public void setPropertiesProvider(PropertiesProvider propertiesProvider) {
this.propertiesProvider = propertiesProvider;
}
private TagSearchService tagSearchService;
public void setTagSearchService(TagSearchService tagSearchService) {
this.tagSearchService = tagSearchService;
}
private SearchProvider searchProvider;
public void setSearchProvider(SearchProvider searchProvider) {
this.searchProvider = searchProvider;
}
/* (non-Javadoc)
* @see org.sakaiproject.entitybus.EntityBroker#entityExists(java.lang.String)
*/
public boolean entityExists(String reference) {
EntityReference ref = entityBrokerManager.parseReference(reference);
boolean exists = entityBrokerManager.entityExists(ref);
return exists;
}
/* (non-Javadoc)
* @see org.sakaiproject.entitybus.EntityBroker#getEntityURL(java.lang.String)
*/
public String getEntityURL(String reference) {
String URL = entityBrokerManager.getEntityURL(reference, null, null);
return URL;
}
/* (non-Javadoc)
* @see org.sakaiproject.entitybus.EntityBroker#getEntityURL(java.lang.String, java.lang.String, java.lang.String)
*/
public String getEntityURL(String reference, String viewKey, String extension) {
String URL = entityBrokerManager.getEntityURL(reference, viewKey, extension);
return URL;
}
/* (non-Javadoc)
* @see org.sakaiproject.entitybus.EntityBroker#getEntityView(java.lang.String, java.lang.String, java.lang.String)
*/
public EntityView getEntityView(String reference, String viewKey, String extension) {
EntityReference ref = parseReference(reference);
EntityView ev = entityBrokerManager.makeEntityView(ref, viewKey, extension);
return ev;
}
/* (non-Javadoc)
* @see org.sakaiproject.entitybus.EntityBroker#isPrefixRegistered(java.lang.String)
*/
public boolean isPrefixRegistered(String prefix) {
boolean registered = false;
if (entityProviderManager.getProviderByPrefix(prefix) != null) {
registered = true;
}
return registered;
}
/* (non-Javadoc)
* @see org.sakaiproject.entitybus.EntityBroker#getRegisteredPrefixes()
*/
public Set<String> getRegisteredPrefixes() {
Set<String> prefixes = entityProviderManager.getRegisteredPrefixes();
return prefixes;
}
/* (non-Javadoc)
* @see org.sakaiproject.entitybus.EntityBroker#parseReference(java.lang.String)
*/
public EntityReference parseReference(String reference) {
EntityReference ref = entityBrokerManager.parseReference(reference);
return ref;
}
/* (non-Javadoc)
* @see org.sakaiproject.entitybus.EntityBroker#fireEvent(java.lang.String, java.lang.String)
*/
public void fireEvent(String eventName, String reference) {
if (eventName == null || "".equals(eventName)) {
throw new IllegalArgumentException("Cannot fire event if name is null or empty");
}
if (reference == null || "".equals(reference)) {
throw new IllegalArgumentException("Cannot fire event if reference is null or empty");
}
if (entityBrokerManager.getExternalIntegrationProvider() != null) {
String refName = reference;
try {
// parse the reference string to validate it and remove any extra bits
EntityReference ref = entityBrokerManager.parseReference(reference);
if (ref != null) {
refName = ref.toString();
} else {
// fallback to simple parsing
refName = new EntityReference(reference).toString();
}
} catch (Exception e) {
refName = reference;
System.err.println("WARN Invalid reference ("+reference+") for eventName ("+eventName+"), could not parse the reference correctly, continuing to create event with original reference");
}
// had to take out the exists check because it makes firing events for removing entities very annoying -AZ
entityBrokerManager.getExternalIntegrationProvider().fireEvent(eventName, refName);
} else {
System.err.println("WARN No external system to handle events: event not fired: " + eventName + ":" + reference);
}
}
/* (non-Javadoc)
* @see org.sakaiproject.entitybus.EntityBroker#fireEntityRequest(java.lang.String, java.lang.String, java.lang.String, java.util.Map, java.lang.Object)
*/
public EntityResponse fireEntityRequest(String reference, String viewKey, String format,
Map<String, String> params, Object entity) {
if (entityBrokerManager.getEntityRESTProvider() != null) {
return entityBrokerManager.getEntityRESTProvider().handleEntityRequest(reference, viewKey, format, params, entity);
} else {
throw new UnsupportedOperationException("No provider to handle fireEntityRequest for ("+reference+","+viewKey+","+format+")");
}
}
/* (non-Javadoc)
* @see org.sakaiproject.entitybus.EntityBroker#fetchEntity(java.lang.String)
*/
public Object fetchEntity(String reference) {
Object entity = null;
EntityReference ref = entityBrokerManager.parseReference(reference);
if (ref == null) {
// not handled in EB so attempt to parse out a prefix and try to get entity from the external system
if (entityBrokerManager.getExternalIntegrationProvider() != null) {
entityBrokerManager.getExternalIntegrationProvider().fetchEntity(reference);
}
} else {
// this is a registered prefix
entity = entityBrokerManager.fetchEntity(ref);
}
return entity;
}
/* (non-Javadoc)
* @see org.sakaiproject.entitybus.EntityBroker#getEntity(java.lang.String)
*/
public EntityData getEntity(String reference) {
EntityReference ref = entityBrokerManager.parseReference(reference);
return entityBrokerManager.getEntityData(ref);
}
/* (non-Javadoc)
* @see org.sakaiproject.entitybus.EntityBroker#fetchEntities(java.lang.String, org.sakaiproject.entitybus.entityprovider.search.Search, java.util.Map)
*/
public List<?> fetchEntities(String prefix, Search search, Map<String, Object> params) {
EntityReference ref = new EntityReference(prefix, "");
List<?> l = null;
try {
requestStorage.setRequestValues(params);
if (params == null) { params = new HashMap<String, Object>(); }
l = entityBrokerManager.fetchEntities(ref, search, params);
} finally {
requestStorage.reset();
}
return l;
}
/* (non-Javadoc)
* @see org.sakaiproject.entitybus.EntityBroker#getEntities(java.lang.String, org.sakaiproject.entitybus.entityprovider.search.Search, java.util.Map)
*/
public List<EntityData> getEntities(String prefix, Search search, Map<String, Object> params) {
EntityReference ref = new EntityReference(prefix, "");
List<EntityData> data = null;
try {
requestStorage.setRequestValues(params);
if (params == null) { params = new HashMap<String, Object>(); }
data = entityBrokerManager.getEntitiesData(ref, search, params);
} finally {
requestStorage.reset();
}
return data;
}
/* (non-Javadoc)
* @see org.sakaiproject.entitybus.EntityBroker#browseEntities(java.lang.String, org.sakaiproject.entitybus.entityprovider.search.Search, java.lang.String, java.lang.String, java.util.Map)
*/
public List<EntityData> browseEntities(String prefix, Search search,
String userReference, String associatedReference, String parentReference, Map<String, Object> params) {
EntityReference parentRef = null;
if (parentReference != null) {
parentRef = entityBrokerManager.parseReference(parentReference);
}
List<EntityData> data = null;
try {
requestStorage.setRequestValues(params);
if (params == null) { params = new HashMap<String, Object>(); }
data = entityBrokerManager.browseEntities(prefix, search, userReference, associatedReference, parentRef, params);
} finally {
requestStorage.reset();
}
return data;
}
/* (non-Javadoc)
* @see org.sakaiproject.entitybus.EntityBroker#getBrowseableEntities(java.lang.String)
*/
public List<BrowseEntity> getBrowseableEntities(String parentPrefix) {
List<BrowseEntity> l = entityBrokerManager.getBrowseableEntities(parentPrefix);
return l;
}
/* (non-Javadoc)
* @see org.sakaiproject.entitybroker.entityprovider.extension.LearningTrackingProvider#registerStatement(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.Boolean, java.lang.Float)
*/
public void registerStatement(String prefix, String actorEmail, String verbStr, String objectURI, Boolean resultSuccess, Float resultScaledScore) {
externalIntegrationProvider.registerStatement(prefix, actorEmail, verbStr, objectURI, resultSuccess, resultScaledScore);
}
public void formatAndOutputEntity(String reference, String format, List<?> entities,
OutputStream output, Map<String, Object> params) {
EntityReference ref = entityBrokerManager.parseReference(reference);
if (ref == null) {
throw new IllegalArgumentException("Cannot output formatted entity, entity reference is invalid: " + reference);
}
if (entityBrokerManager.getEntityRESTProvider() != null) {
try {
requestStorage.setRequestValues(params);
// convert entities to entity data list
List<EntityData> data = entityBrokerManager.convertToEntityData(entities, ref);
if (params == null) { params = new HashMap<String, Object>(); }
entityBrokerManager.getEntityRESTProvider().formatAndOutputEntity(ref, format, data, output, params);
} finally {
requestStorage.reset();
}
} else {
throw new UnsupportedOperationException("No provider to handle formatAndOutputEntity for ("+reference+","+format+")");
}
}
public Object translateInputToEntity(String reference, String format, InputStream input,
Map<String, Object> params) {
EntityReference ref = entityBrokerManager.parseReference(reference);
if (ref == null) {
throw new IllegalArgumentException("Cannot output formatted entity, entity reference is invalid: " + reference);
}
Object entity = null;
if (entityBrokerManager.getEntityRESTProvider() != null) {
try {
requestStorage.setRequestValues(params);
if (params == null) { params = new HashMap<String, Object>(); }
entity = entityBrokerManager.getEntityRESTProvider().translateInputToEntity(ref, format, input, params);
} finally {
requestStorage.reset();
}
} else {
throw new UnsupportedOperationException("No provider to handle translateInputToEntity for ("+reference+","+format+")");
}
return entity;
}
public ActionReturn executeCustomAction(String reference, String action,
Map<String, Object> params, OutputStream outputStream) {
EntityReference ref = entityBrokerManager.parseReference(reference);
if (ref == null) {
throw new IllegalArgumentException("Invalid entity reference, no provider found to handle this ref: " + reference);
}
ActionsExecutable actionProvider = entityProviderManager.getProviderByPrefixAndCapability(ref.getPrefix(), ActionsExecutable.class);
if (actionProvider == null) {
throw new IllegalArgumentException("The provider for prefix ("+ref.getPrefix()+") cannot handle custom actions");
}
ActionReturn ar = null;
if (entityBrokerManager.getEntityRESTProvider() != null) {
try {
requestStorage.setRequestValues(params);
if (params == null) { params = new HashMap<String, Object>(0); }
EntityView view = entityBrokerManager.parseEntityURL(reference);
ar = entityBrokerManager.getEntityRESTProvider().handleCustomActionExecution(actionProvider, ref, action, params, outputStream, view, null);
// populate the entity data
if (ar != null) {
if (ar.entitiesList != null) {
entityBrokerManager.populateEntityData(ar.entitiesList);
} else if (ar.entityData != null) {
entityBrokerManager.populateEntityData( new EntityData[] {ar.entityData} );
}
}
} finally {
requestStorage.reset();
}
} else {
throw new UnsupportedOperationException("No provider to handle executeCustomAction for ("+reference+","+action+")");
}
return ar;
}
// PROPERTIES
public List<String> findEntityRefs(String[] prefixes, String[] name, String[] searchValue,
boolean exactMatch) {
if (propertiesProvider != null) {
return propertiesProvider.findEntityRefs(prefixes, name, searchValue, exactMatch);
} else {
System.err.println("WARN No propertiesProvider defined");
return new ArrayList<String>();
}
}
public Map<String, String> getProperties(String reference) {
if (propertiesProvider != null) {
return propertiesProvider.getProperties(reference);
} else {
System.err.println("WARN No propertiesProvider defined");
return new HashMap<String, String>(0);
}
}
public String getPropertyValue(String reference, String name) {
if (propertiesProvider != null) {
return propertiesProvider.getPropertyValue(reference, name);
} else {
System.err.println("WARN No propertiesProvider defined");
return null;
}
}
public void setPropertyValue(String reference, String name, String value) {
if (propertiesProvider != null) {
propertiesProvider.setPropertyValue(reference, name, value);
} else {
System.err.println("WARN No propertiesProvider defined");
}
}
// TAGS
public List<EntityData> findEntitesByTags(String[] tags, String[] prefixes,
boolean matchAll, Search search, Map<String, Object> params) {
if (tagSearchService != null) {
requestStorage.setRequestValues(params);
List<EntityData> results = tagSearchService.findEntitesByTags(tags, prefixes, matchAll, search);
requestStorage.reset();
return results;
} else {
System.err.println("WARN No tagSearchService defined");
return new ArrayList<EntityData>();
}
}
public List<String> getTagsForEntity(String reference) {
if (tagSearchService != null) {
return tagSearchService.getTagsForEntity(reference);
} else {
System.err.println("WARN No tagSearchService defined");
return new ArrayList<String>();
}
}
public void removeTagsFromEntity(String reference, String[] tags) {
if (tagSearchService != null) {
tagSearchService.removeTagsFromEntity(reference, tags);
} else {
System.err.println("WARN No tagSearchService defined");
}
}
public void addTagsToEntity(String reference, String[] tags) {
if (tagSearchService != null) {
tagSearchService.addTagsToEntity(reference, tags);
} else {
System.err.println("WARN No tagSearchService defined");
}
}
public void setTagsForEntity(String reference, String[] tags) {
if (tagSearchService != null) {
tagSearchService.setTagsForEntity(reference, tags);
} else {
System.err.println("WARN No tagSearchService defined");
}
}
/**
* @deprecated use {@link #getTagsForEntity(String)}
*/
public Set<String> getTags(String reference) {
if (tagSearchService != null) {
return new HashSet<String>( tagSearchService.getTagsForEntity(reference) );
} else {
System.err.println("WARN No tagSearchService defined");
return new HashSet<String>();
}
}
/**
* @deprecated use {@link #setTagsForEntity(String, String[])}
*/
public void setTags(String reference, String[] tags) {
if (tagSearchService != null) {
tagSearchService.setTagsForEntity(reference, tags);
} else {
System.err.println("WARN No tagSearchService defined");
}
}
/**
* @deprecated use {@link #findEntitesByTags(String[], String[], boolean, Search)}
*/
public List<String> findEntityRefsByTags(String[] tags) {
if (tagSearchService != null) {
ArrayList<String> refs = new ArrayList<String>();
List<EntityData> results = tagSearchService.findEntitesByTags(tags, null, false, null);
for (EntityData entitySearchResult : results) {
refs.add( entitySearchResult.getEntityReference() );
}
return refs;
} else {
System.err.println("WARN No tagSearchService defined");
return new ArrayList<String>();
}
}
// SEARCH methods
public boolean add(String reference, SearchContent content) {
if (searchProvider != null) {
return searchProvider.add(reference, content);
}
System.err.println("WARN No searchProvider defined");
return false;
}
public boolean remove(String reference) {
if (searchProvider != null) {
return searchProvider.remove(reference);
}
System.err.println("WARN No searchProvider defined");
return false;
}
public SearchResults search(QuerySearch query) {
if (searchProvider != null) {
return searchProvider.search(query);
}
System.err.println("WARN No searchProvider defined");
return null;
}
public void resetSearchIndexes(String context) {
if (searchProvider != null) {
searchProvider.resetSearchIndexes(context);
}
}
}