/** * $Id: EntityBrokerManagerImpl.java 105077 2012-02-24 22:54:29Z ottenhoff@longsight.com $ * $URL: https://source.sakaiproject.org/svn/entitybroker/trunk/impl/src/java/org/sakaiproject/entitybroker/impl/EntityBrokerManagerImpl.java $ * EntityBrokerManager.java - entity-broker - Jul 22, 2008 11:33:39 AM - azeckoski ************************************************************************** * Copyright (c) 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.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletResponse; import org.azeckoski.reflectutils.ConstructorUtils; import org.azeckoski.reflectutils.ReflectUtils; import org.azeckoski.reflectutils.exceptions.FieldnameNotFoundException; import org.sakaiproject.entitybroker.EntityBrokerManager; import org.sakaiproject.entitybroker.EntityReference; import org.sakaiproject.entitybroker.EntityView; import org.sakaiproject.entitybroker.access.AccessViews; import org.sakaiproject.entitybroker.access.EntityViewAccessProvider; import org.sakaiproject.entitybroker.access.EntityViewAccessProviderManager; import org.sakaiproject.entitybroker.entityprovider.CoreEntityProvider; import org.sakaiproject.entitybroker.entityprovider.EntityProvider; import org.sakaiproject.entitybroker.entityprovider.EntityProviderManager; import org.sakaiproject.entitybroker.entityprovider.EntityProviderMethodStore; import org.sakaiproject.entitybroker.entityprovider.annotations.EntityTitle; import org.sakaiproject.entitybroker.entityprovider.capabilities.BrowseNestable; import org.sakaiproject.entitybroker.entityprovider.capabilities.BrowseSearchable; import org.sakaiproject.entitybroker.entityprovider.capabilities.Browseable; import org.sakaiproject.entitybroker.entityprovider.capabilities.BrowseableCollection; import org.sakaiproject.entitybroker.entityprovider.capabilities.CollectionResolvable; import org.sakaiproject.entitybroker.entityprovider.capabilities.Describeable; import org.sakaiproject.entitybroker.entityprovider.capabilities.EntityViewUrlCustomizable; import org.sakaiproject.entitybroker.entityprovider.capabilities.ReferenceParseable; import org.sakaiproject.entitybroker.entityprovider.capabilities.Resolvable; import org.sakaiproject.entitybroker.entityprovider.capabilities.Sampleable; import org.sakaiproject.entitybroker.entityprovider.extension.BrowseEntity; import org.sakaiproject.entitybroker.entityprovider.extension.EntityData; import org.sakaiproject.entitybroker.entityprovider.extension.RequestGetterWrite; import org.sakaiproject.entitybroker.entityprovider.extension.RequestStorageWrite; import org.sakaiproject.entitybroker.entityprovider.search.Search; import org.sakaiproject.entitybroker.exception.EntityException; import org.sakaiproject.entitybroker.providers.EntityPropertiesService; import org.sakaiproject.entitybroker.providers.EntityRESTProvider; import org.sakaiproject.entitybroker.providers.ExternalIntegrationProvider; import org.sakaiproject.entitybroker.util.EntityDataUtils; import org.sakaiproject.entitybroker.util.request.RequestUtils; /** * This is the internal service for handling entities, * most of the work done by entity broker is handled here<br/> * This should be used in * preference to the EntityBroker directly by implementation classes * that are part of the EntityBroker system, * rather than the user-facing EntityBroker directly. * * @author Aaron Zeckoski (azeckoski @ gmail.com) */ public class EntityBrokerManagerImpl implements EntityBrokerManager { public static String SVN_REVISION = "$Revision: 105077 $"; public static String SVN_LAST_UPDATE = "$Date: 2012-02-24 17:54:29 -0500 (Fri, 24 Feb 2012) $"; public String getVersionInfo() { return "MANAGER:: SVN: " + SVN_REVISION + " : " + SVN_LAST_UPDATE; } public EntityBrokerManagerImpl() { } /** * Full constructor */ public EntityBrokerManagerImpl(EntityProviderManager entityProviderManager, EntityPropertiesService entityPropertiesService, EntityViewAccessProviderManager entityViewAccessProviderManager) { this(entityProviderManager, entityPropertiesService, entityViewAccessProviderManager, null); } /** * Constructor with optional {@link ExternalIntegrationProvider} */ public EntityBrokerManagerImpl(EntityProviderManager entityProviderManager, EntityPropertiesService entityPropertiesService, EntityViewAccessProviderManager entityViewAccessProviderManager, ExternalIntegrationProvider externalIntegrationProvider) { super(); if (entityProviderManager == null) { throw new IllegalArgumentException("entityProviderManager cannot be null"); } this.entityProviderManager = entityProviderManager; this.entityPropertiesService = entityPropertiesService; this.entityViewAccessProviderManager = entityViewAccessProviderManager; this.externalIntegrationProvider = externalIntegrationProvider; } public void init() { // Set the maximum depth of object graph which can be transcoded into JSON. // An integer between 4 and 26. Anything below 5 is set at 5, anything above 25 is set to 25. String maxJSONLevelString = externalIntegrationProvider.getMaxJSONLevel(); try { maxJSONLevel = Integer.parseInt(maxJSONLevelString); if(this.maxJSONLevel < 5) { this.maxJSONLevel = 5; } else if(this.maxJSONLevel > 25) { this.maxJSONLevel = 25; } } catch(NumberFormatException nfe) { } } private EntityProviderManager entityProviderManager; private EntityPropertiesService entityPropertiesService; private EntityViewAccessProviderManager entityViewAccessProviderManager; private ExternalIntegrationProvider externalIntegrationProvider; private EntityRESTProvider entityRESTProvider; private int maxJSONLevel = 7; /* (non-Javadoc) * @see org.sakaiproject.entitybroker.EntityBrokerManager#getMaxJSONLevel() */ public int getMaxJSONLevel() { return maxJSONLevel; } private String defaultServletContext = RequestUtils.getServletContext(null); /** * We have to do something fairly tricky here because we really need this to be handled * on a per thread basis (or at least a per servlet basis anyway) so we need to store the "default" * and then also store a threadlocal for each servlet to set and fallback if the TL is not set, * what a giant PITA but this should allow multiple servlets to instantiate the EB handlers */ private final ThreadLocal<String> localServletContext = new ThreadLocal<String>(); /* (non-Javadoc) * @see org.sakaiproject.entitybroker.EntityBrokerManager#setServletContext(java.lang.String) */ public void setServletContext(String servletContext) { if (servletContext != null) { this.localServletContext.set(servletContext); } else { this.localServletContext.set(null); } } /* (non-Javadoc) * @see org.sakaiproject.entitybroker.EntityBrokerManager#getServletContext() */ public String getServletContext() { String context = this.defaultServletContext; if (this.localServletContext != null && this.localServletContext.get() != null) { context = this.localServletContext.get(); } return context; } /** * Determines if an entity exists based on the reference * * @param reference an entity reference object * @return true if entity exists, false otherwise */ public boolean entityExists(EntityReference ref) { boolean exists = false; if (ref != null) { EntityProvider provider = entityProviderManager.getProviderByPrefix(ref.getPrefix()); if (provider == null) { // no provider found so no entity can't exist exists = false; } else if (!(provider instanceof CoreEntityProvider)) { // no core provider so assume it does exist exists = true; } else { if (ref.getId() == null) { // currently we assume exists if it is only a prefix exists = true; } else { exists = ((CoreEntityProvider) provider).entityExists( ref.getId() ); } } } return exists; } /** * Creates the full URL to an entity using the sakai {@link ServerConfigurationService}, * (e.g. http://server:8080/direct/entity/123/)<br/> * <br/> * <b>Note:</b> the webapp name (relative URL path) of the direct servlet, of "/direct" * is hardcoded into this method, and the * {@link org.sakaiproject.entitybroker.util.servlet.DirectServlet} must be deployed there on this * server. * * @param reference a globally unique reference to an entity, * consists of the entity prefix and optionally the local id * @param viewKey the specific view type to get the URL for, * can be null to determine the key automatically * @param extension the optional extension to add to the end, * can be null to use no extension * @return the full URL to a specific entity or space */ public String getEntityURL(String reference, String viewKey, String extension) { // ensure this is a valid reference first EntityReference ref = parseReference(reference); EntityView view = makeEntityView(ref, viewKey, extension); String url = makeFullURL(view.toString()); return url; } /** * Make a full URL (http://....) from just a path URL (/prefix/id.xml) */ public String makeFullURL(String pathURL) { String serverUrl = "http://localhost:8080"; if (externalIntegrationProvider != null) { serverUrl = externalIntegrationProvider.getServerUrl(); } String url = serverUrl + getServletContext() + pathURL; return url; } /** * Reduce code duplication and ensure custom templates are used */ public EntityView makeEntityView(EntityReference ref, String viewKey, String extension) { if (ref == null) { throw new IllegalArgumentException("ref cannot be null"); } EntityView view = new EntityView(); EntityViewUrlCustomizable custom = (EntityViewUrlCustomizable) entityProviderManager .getProviderByPrefixAndCapability(ref.getPrefix(), EntityViewUrlCustomizable.class); if (custom != null) { // use the custom parsing templates view.loadParseTemplates( custom.getParseTemplates() ); } view.setEntityReference(ref); if (viewKey != null) { view.setViewKey(viewKey); } if (extension != null) { view.setExtension(extension); } return view; } /** * Parses an entity reference into the appropriate reference form * * @param reference a unique entity reference * @return the entity reference object or * null if there is no provider found for the prefix parsed out * @throws IllegalArgumentException if there is a failure during parsing */ public EntityReference parseReference(String reference) { String prefix = EntityReference.getPrefix(reference); EntityReference ref = null; if (entityProviderManager.getProviderByPrefix(prefix) != null) { ReferenceParseable provider = entityProviderManager.getProviderByPrefixAndCapability(prefix, ReferenceParseable.class); if (provider == null) { ref = new EntityReference(reference); } else { EntityReference exemplar = provider.getParsedExemplar(); if (exemplar == null) { ref = new EntityReference(reference); } else { if (exemplar.getClass() == EntityReference.class) { ref = new EntityReference(reference); } else { // construct the custom class and then return it try { Constructor<? extends Object> m = exemplar.getClass().getConstructor(String.class); ref = (EntityReference) m.newInstance(reference); } catch (SecurityException e) { throw new RuntimeException("Failed to invoke a constructor which takes a single string " + "(reference="+reference+") for class: " + exemplar.getClass(), e); } catch (IllegalArgumentException e) { throw new RuntimeException("Failed to invoke a constructor which takes a single string " + "(reference="+reference+") for class: " + exemplar.getClass(), e); } catch (NoSuchMethodException e) { throw new RuntimeException("Failed to invoke a constructor which takes a single string " + "(reference="+reference+") for class: " + exemplar.getClass(), e); } catch (InstantiationException e) { throw new RuntimeException("Failed to invoke a constructor which takes a single string " + "(reference="+reference+") for class: " + exemplar.getClass(), e); } catch (IllegalAccessException e) { throw new RuntimeException("Failed to invoke a constructor which takes a single string " + "(reference="+reference+") for class: " + exemplar.getClass(), e); } catch (InvocationTargetException e) { throw new RuntimeException("Failed to invoke a constructor which takes a single string " + "(reference="+reference+") for class: " + exemplar.getClass(), e); } } } } } return ref; } /** * Parses an entity URL into an entity view object, * handles custom parsing templates * * @param entityURL an entity URL * @return the entity view object representing this URL or * null if there is no provider found for the prefix parsed out * @throws IllegalArgumentException if there is a failure during parsing */ public EntityView parseEntityURL(String entityURL) { if (entityURL == null || "".equals(entityURL)) { throw new IllegalArgumentException("entityURL cannot be null or empty"); } // strip off the /direct if this url starts with that if (entityURL.startsWith(EntityView.DIRECT_PREFIX)) { entityURL = entityURL.substring(EntityView.DIRECT_PREFIX.length()); } EntityView view = null; // first get the prefix String prefix = EntityReference.getPrefix(entityURL); // get the basic provider to see if this prefix is valid EntityProvider provider = entityProviderManager.getProviderByPrefix(prefix); if (provider != null) { // this prefix is valid so check for custom entity templates EntityViewUrlCustomizable custom = (EntityViewUrlCustomizable) entityProviderManager .getProviderByPrefixAndCapability(prefix, EntityViewUrlCustomizable.class); if (custom == null) { view = new EntityView(entityURL); } else { // use the custom parsing templates to build the object view = new EntityView(); view.loadParseTemplates( custom.getParseTemplates() ); view.parseEntityURL(entityURL); } } return view; } /** * Get an entity object of some kind for this reference if it has an id, * will simply return null if no id is available in this reference * * @param ref an entity reference * @return the entity object for this reference OR null if none can be retrieved */ public Object fetchEntity(EntityReference ref) { if (ref == null) { throw new IllegalArgumentException("ref cannot be null"); } Object entity = fetchEntityObject(ref); if (entity != null) { entity = EntityDataUtils.convertToEntity(entity); } return entity; } /** * Get the entity data for a reference if possible * * @param ref an entity reference * @return an {@link EntityData} object for this reference if one can be found OR null if not */ public EntityData getEntityData(EntityReference ref) { if (ref == null) { throw new IllegalArgumentException("ref cannot be null"); } EntityData ed = null; Object obj = fetchEntityObject(ref); if (obj != null) { ed = EntityDataUtils.makeEntityData(ref, obj); populateEntityData(new EntityData[] {ed} ); } else { if (entityExists(ref)) { String url = getEntityURL(ref.toString(), EntityView.VIEW_SHOW, null); ed = new EntityData(ref, (String)null); ed.setEntityURL(url); } } return ed; } /** * Get the entity without a change (may be EntityData or just an object) */ protected Object fetchEntityObject(EntityReference ref) { Object entity = null; Resolvable provider = entityProviderManager.getProviderByPrefixAndCapability(ref.getPrefix(), Resolvable.class); if (provider != null) { entity = provider.getEntity(ref); } return entity; } /** * Get a list of entities from {@link CollectionResolvable} first if available or {@link BrowseSearchable} if not, * returns the entities as actual entities (converts from {@link EntityData} if that was used), * correctly handles references to single entities as well * * @param ref the reference * @param search a search (should not be null) * @param params * @return a list of entities OR empty list if none found for the given reference */ public List<?> fetchEntities(EntityReference ref, Search search, Map<String, Object> params) { List<?> entities = internalGetEntities(ref, search, params); entities = EntityDataUtils.convertToEntities(entities); return entities; } /** * Get a list of entities from {@link CollectionResolvable} first if available or {@link BrowseSearchable} if not, * returns the entities wrapped in {@link EntityData}, * correctly handles references to single entities as well * * @param ref the reference * @param search a search (should not be null) * @param params * @return a list of entities OR empty list if none found for the given reference */ public List<EntityData> getEntitiesData(EntityReference ref, Search search, Map<String, Object> params) { List<?> entities = internalGetEntities(ref, search, params); List<EntityData> data = convertToEntityData(entities, ref); return data; } /** * Fetches the browseable entities * @param prefix * @param search * @param userReference * @param associatedReference * @param parentEntityRef * @param params * @return a list of entity data results to browse */ public List<EntityData> browseEntities(String prefix, Search search, String userReference, String associatedReference, EntityReference parentEntityRef, Map<String, Object> params) { if (prefix == null) { throw new IllegalArgumentException("No prefix supplied for entity browsing resolution, prefix was null"); } List<EntityData> results = null; search = EntityDataUtils.translateStandardSearch(search); if (parentEntityRef != null) { // do the special call to get nested children items BrowseNestable nestable = entityProviderManager.getProviderByPrefixAndCapability(prefix, BrowseNestable.class); if (nestable != null) { List<EntityData> l = nestable.getChildrenEntities(parentEntityRef, search, userReference, associatedReference, params); if (l != null) { results = new ArrayList<EntityData>( l ); } populateEntityData( l ); } } else { // check for browse searchable first BrowseSearchable searchable = entityProviderManager.getProviderByPrefixAndCapability(prefix, BrowseSearchable.class); if (searchable != null) { List<EntityData> l = searchable.browseEntities(search, userReference, associatedReference, params); if (l != null) { results = new ArrayList<EntityData>( l ); } populateEntityData( l ); } else { // get from the collection if available BrowseableCollection provider = entityProviderManager.getProviderByPrefixAndCapability(prefix, BrowseableCollection.class); if (provider != null) { EntityReference ref = new EntityReference(prefix, ""); List<?> l = getEntitiesData(ref, search, params); results = convertToEntityData(l, ref); } } } if (results == null) { results = new ArrayList<EntityData>(); } return results; } /** * Get the meta data about browseable entities * @param parentPrefix the prefix of the parent type (null for the root types) * @return the list of browseable entity meta data */ public List<BrowseEntity> getBrowseableEntities(String parentPrefix) { Map<String, BrowseEntity> results = new HashMap<String, BrowseEntity>(); // first we sorta have to get all the browseable entities info List<Browseable> browseableProviders = entityProviderManager.getProvidersByCapability(Browseable.class); for (Browseable browseable : browseableProviders) { String prefix = browseable.getEntityPrefix(); // add the current prefix to the list of browseable entities BrowseEntity currentBE = results.get(prefix); if (currentBE == null) { currentBE = new BrowseEntity(prefix); results.put(prefix, currentBE); } BrowseNestable bnProvider = entityProviderManager.getProviderByPrefixAndCapability(prefix, BrowseNestable.class); if (bnProvider != null) { // this must be a non-root node results.put(prefix, new BrowseEntity(prefix)); String parent = bnProvider.getParentprefix(); currentBE.setParentPrefix(parent); // add this parent prefix to current BrowseEntity parentBE = results.get(parent); // make the parent if it does not exist yet if (parentBE == null) { parentBE = new BrowseEntity(parent); results.put(parent, parentBE); } parentBE.addNestedPrefix(prefix); // add the child prefix to the parent } // add in the title/desc if available Describeable dProvider = entityProviderManager.getProviderByPrefixAndCapability(prefix, Describeable.class); if (dProvider != null) { String title = entityPropertiesService.getProperty(prefix, Browseable.BROWSE_TITLE_KEY); String description = entityPropertiesService.getProperty(prefix, Browseable.BROWSE_DESC_KEY); currentBE.setTitleDesc(title, description); } // add in the access views info EntityViewAccessProvider evap = entityViewAccessProviderManager.getProvider(prefix); if (evap != null) { if (AccessViews.class.isAssignableFrom(evap.getClass())) { String[] entityViewKeys = ((AccessViews)evap).getHandledEntityViews(); currentBE.setEntityViewKeys(entityViewKeys); } } } // now filter down to what was asked for only List<BrowseEntity> l = new ArrayList<BrowseEntity>(); for (BrowseEntity browseEntity : results.values()) { if (parentPrefix == null) { // get root items only if (browseEntity.getParentPrefix() == null) { l.add(browseEntity); } } else { // get items with matching parents only if (browseEntity.getParentPrefix() != null && parentPrefix.equals(browseEntity.getParentPrefix())) { l.add(browseEntity); } } } Collections.sort(l, new BrowseEntity.TitleComparator()); return l; } /** * INTERNAL usage: * Get a list of entities from {@link CollectionResolvable} first if available or {@link BrowseSearchable} if not, * returns the entities as whatever they were returned as, EntityData would need to be populated still, * correctly handles references to single entities as well * * @param ref the reference * @param search a search (should not be null) * @param params * @return a list of entities OR empty list if none found for the given reference */ @SuppressWarnings({ "unchecked", "rawtypes" }) protected List<?> internalGetEntities(EntityReference ref, Search search, Map<String, Object> params) { if (ref == null) { throw new IllegalArgumentException("No reference supplied for entity collection resolution, ref was null"); } // get the entities to output List entities = null; if (ref.getId() == null) { // encoding a collection of entities CollectionResolvable provider = entityProviderManager.getProviderByPrefixAndCapability(ref.getPrefix(), CollectionResolvable.class); if (provider != null) { search = EntityDataUtils.translateStandardSearch(search); List<?> l = provider.getEntities(ref, search); if (l != null) { entities = new ArrayList( l ); } } else { BrowseSearchable searchable = entityProviderManager.getProviderByPrefixAndCapability(ref.getPrefix(), BrowseSearchable.class); if (searchable != null) { search = EntityDataUtils.translateStandardSearch(search); List<?> l = searchable.browseEntities(search, null, null, params); if (l != null) { entities = new ArrayList( l ); } } } } else { // encoding a single entity Object entity = fetchEntityObject(ref); if (entity == null) { throw new EntityException("Failed to retrieve entity (" + ref + "), entity object could not be found", ref.toString(), HttpServletResponse.SC_NOT_FOUND); } entities = new ArrayList(1); entities.add(entity); } // make sure no null is returned if (entities == null) { entities = new ArrayList<String>(); } return entities; } /** * Convert a list of objects to entity data objects (also populates them), * will preserve null (i.e. null in => null out) */ public List<EntityData> convertToEntityData(List<?> entities, EntityReference ref) { List<EntityData> l = EntityDataUtils.convertToEntityData(entities, ref); populateEntityData(l); return l; } /** * Convert a single object to an entity data object (also populates it), * will preserve null (i.e. null in => null out) */ public EntityData convertToEntityData(Object entity, EntityReference ref) { EntityData ed = EntityDataUtils.convertToEntityData(entity, ref); if (ed != null) { populateEntityData( new EntityData[] {ed} ); } return ed; } /** * Add in the extra meta data (URL, title, etc.) to all entity data objects, * handles it as efficiently as possible without remaking an entity view on every call, * this is fail safe (i.e. it should throw no exceptions) * * @param data a list of entity data */ public void populateEntityData(List<EntityData> data) { if (data != null && ! data.isEmpty()) { populateEntityData(data.toArray(new EntityData[data.size()])); } } /** * Add in the extra meta data (URL, title, etc.) to all entity data objects, * handles it as efficiently as possible without remaking an entity view on every call, * this is fail safe (i.e. it should throw no exceptions) * * @param data a list of entity data */ public void populateEntityData(EntityData[] data) { if (data == null) { return; } HashMap<String, EntityView> views = new HashMap<String, EntityView>(); for (EntityData entityData : data) { if (entityData.isPopulated() || entityData.isDataOnly()) { continue; } else { entityData.setPopulated(true); } // set URL EntityReference ref = entityData.getEntityRef(); EntityView view = null; if (views.containsKey(ref.getPrefix())) { view = views.get(ref.getPrefix()); } else { view = makeEntityView(ref, EntityView.VIEW_SHOW, null); views.put(ref.getPrefix(), view); } view.setEntityReference(ref); String partialURL = view.getEntityURL(); String fullURL = makeFullURL( partialURL ); entityData.setEntityURL( fullURL ); // check what we are dealing with boolean isPOJO = false; if (entityData.getData() != null) { if ( ConstructorUtils.isClassBean(entityData.getData().getClass()) ) { isPOJO = true; } } // attempt to set display title if not set if (! entityData.isDisplayTitleSet()) { boolean titleNotSet = true; // check properties first if (entityData.getEntityProperties() != null) { String title = EntityDataUtils.findMapStringValue(entityData.getEntityProperties(), new String[] {"displayTitle","title","displayName","name"}); if (title != null) { entityData.setDisplayTitle(title); titleNotSet = false; } } // check the object itself next if (isPOJO && titleNotSet) { try { String title = ReflectUtils.getInstance().getFieldValueAsString(entityData.getData(), "title", EntityTitle.class); if (title != null) { entityData.setDisplayTitle(title); titleNotSet = false; } } catch (FieldnameNotFoundException e) { // could not find any fields with the title, nothing to do but continue } } } // done with this entity data } } /** * Safely get the sample entity object which is defined for a prefix, * if there is not one then return null * @param prefix the entity prefix * @param id (optional) will get the actual entity for this id as a sample * @return a sample object OR null if none can be found */ public Object getSampleEntityObject(String prefix, String id) { Object entity = null; if (id != null) { // get the current entity if possible try { Resolvable resolvable = entityProviderManager.getProviderByPrefixAndCapability(prefix, Resolvable.class); if (resolvable != null) { entity = resolvable.getEntity( new EntityReference(prefix, id) ); } } catch (RuntimeException e) { // failed to get it entity = null; } } if (entity == null) { // get a sample entity if possible try { Sampleable sampleable = entityProviderManager.getProviderByPrefixAndCapability(prefix, Sampleable.class); if (sampleable != null) { entity = sampleable.getSampleEntity(); } } catch (RuntimeException e) { entity = null; } if (entity == null) { // get an entity from resolveable as a last resort try { Resolvable resolvable = entityProviderManager.getProviderByPrefixAndCapability(prefix, Resolvable.class); if (resolvable != null) { entity = resolvable.getEntity( new EntityReference(prefix, "") ); } } catch (RuntimeException e) { entity = null; } } } return entity; } // GETTERS /* (non-Javadoc) * @see org.sakaiproject.entitybroker.EntityBrokerManager#getEntityRESTProvider() */ public EntityRESTProvider getEntityRESTProvider() { return entityRESTProvider; } /* (non-Javadoc) * @see org.sakaiproject.entitybroker.impl.EntityBrokerManager#getExternalIntegrationProvider() */ public ExternalIntegrationProvider getExternalIntegrationProvider() { return this.externalIntegrationProvider; } /* (non-Javadoc) * @see org.sakaiproject.entitybroker.EntityBrokerManager#getEntityProviderManager() */ public EntityProviderManager getEntityProviderManager() { return entityProviderManager; } /* (non-Javadoc) * @see org.sakaiproject.entitybroker.EntityBrokerManager#getEntityPropertiesService() */ public EntityPropertiesService getEntityPropertiesService() { return entityPropertiesService; } /* (non-Javadoc) * @see org.sakaiproject.entitybroker.EntityBrokerManager#getEntityViewAccessProviderManager() */ public EntityViewAccessProviderManager getEntityViewAccessProviderManager() { return entityViewAccessProviderManager; } /* (non-Javadoc) * @see org.sakaiproject.entitybroker.EntityBrokerManager#getEntityProviderMethodStore() */ public EntityProviderMethodStore getEntityProviderMethodStore() { return entityProviderManager.getEntityProviderMethodStore(); } /* (non-Javadoc) * @see org.sakaiproject.entitybroker.EntityBrokerManager#getRequestGetter() */ public RequestGetterWrite getRequestGetter() { return entityProviderManager.getRequestGetter(); } /* (non-Javadoc) * @see org.sakaiproject.entitybroker.EntityBrokerManager#getRequestStorage() */ public RequestStorageWrite getRequestStorage() { return entityProviderManager.getRequestStorage(); } // SETTERS /* (non-Javadoc) * @see org.sakaiproject.entitybroker.EntityBrokerManager#setEntityRESTProvider(org.sakaiproject.entitybroker.providers.EntityRESTProvider) */ public void setEntityRESTProvider(EntityRESTProvider entityRESTProvider) { this.entityRESTProvider = entityRESTProvider; } /* (non-Javadoc) * @see org.sakaiproject.entitybroker.EntityBrokerManager#setExternalIntegrationProvider(org.sakaiproject.entitybroker.providers.ExternalIntegrationProvider) */ public void setExternalIntegrationProvider(ExternalIntegrationProvider externalIntegrationProvider) { this.externalIntegrationProvider = externalIntegrationProvider; } public void setEntityProviderManager(EntityProviderManager entityProviderManager) { this.entityProviderManager = entityProviderManager; } public void setEntityPropertiesService(EntityPropertiesService entityPropertiesService) { this.entityPropertiesService = entityPropertiesService; } public void setEntityViewAccessProviderManager( EntityViewAccessProviderManager entityViewAccessProviderManager) { this.entityViewAccessProviderManager = entityViewAccessProviderManager; } }