/********************************************************************************** * $URL: https://source.sakaiproject.org/svn/rwiki/trunk/rwiki-impl/impl/src/java/uk/ac/cam/caret/sakai/rwiki/component/service/impl/BaseEntityHandlerImpl.java $ * $Id: BaseEntityHandlerImpl.java 74213 2010-03-05 04:48:15Z steve.swinsburg@gmail.com $ *********************************************************************************** * * Copyright (c) 2003, 2004, 2005, 2006 The Sakai Foundation. * * Licensed under the Educational Community License, Version 1.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/ecl1.php * * 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 uk.ac.cam.caret.sakai.rwiki.component.service.impl; import java.text.MessageFormat; import org.sakaiproject.alias.api.AliasService; import org.sakaiproject.component.cover.ServerConfigurationService; import org.sakaiproject.entity.api.Entity; import org.sakaiproject.entity.api.Reference; import org.sakaiproject.entity.cover.EntityManager; import org.sakaiproject.exception.IdUnusedException; import org.sakaiproject.site.api.SiteService; import uk.ac.cam.caret.sakai.rwiki.service.api.EntityHandler; import uk.ac.cam.caret.sakai.rwiki.utils.NameHelper; /** * Provides a regex base entity handler where the matching uses MessageFormats * and Regex patterns * * @author ieb */ public abstract class BaseEntityHandlerImpl implements EntityHandler { /** * The start of the URL endign in a / */ private String accessURLStart = null; /** * The sub type of this handler, but be unique in the context of the major * type */ private String minorType = null; /** * if the eh provides a link, this URL will give the link */ private String feedFormat; /** Configuration: allow use of alias for site id in references. */ protected boolean m_siteAlias = true; private boolean experimental = false; private boolean setup = false; private boolean available = true; /** Dependency: AliasService. */ protected AliasService m_aliasService = null; /** * Dependency: AliasService. * * @param service * The AliasService. */ public void setAliasService(AliasService service) { m_aliasService = service; } /** Dependency: SiteService. */ protected SiteService m_siteService = null; /** * Dependency: SiteService. * * @param service * The SiteService. */ public void setSiteService(SiteService service) { m_siteService = service; } /** * {@inheritDoc} */ public void setReference(String majorType, Reference ref, String reference) { if (!isAvailable()) return; Decoded decoded = decode(reference); if (decoded != null) { ref.set(majorType, minorType, decoded.getId(), decoded .getContainer(), decoded.getContext()); } else { throw new RuntimeException(this + " Failed to setReference in EntityHelper " + majorType + ":" + minorType + " reference not for this EntityHandler "); } } /** * {@inheritDoc} */ public boolean matches(String reference) { if (!isAvailable()) return false; return (decode(reference) != null); } /** * {@inheritDoc} */ public int getRevision(Reference reference) { if (!isAvailable()) return 0; Decoded decode = decode(reference.getReference()); return Integer.parseInt(decode.getVersion()); } /** * @return Returns the minorType. */ public String getMinorType() { return minorType; } /** * @param minorType * The minorType to set. */ public void setMinorType(String minorType) { this.minorType = minorType; } /** * @param s * the full reference * @return A Decoded object contianing the values, or null if not this * handler */ public Decoded decode(String s) { String ending = "." + minorType; if (isAvailable() && s.startsWith(accessURLStart) && s.endsWith(ending) && s.indexOf("//") == -1 ) { Decoded decoded = new Decoded(); s = s.substring(accessURLStart.length() - 1); int lastslash = s.lastIndexOf(Entity.SEPARATOR); int firstslash = s.indexOf(Entity.SEPARATOR, 1); int nextslash = s.indexOf(Entity.SEPARATOR, firstslash + 1); if (nextslash == -1) { nextslash = firstslash; } String siteContext = s.substring(0, nextslash); String context; int slashIndex = siteContext.indexOf(Entity.SEPARATOR, 1); if (slashIndex == -1) { context = ""; } else { context = s.substring (slashIndex + 1, siteContext.length()); } // recognize alias for site id - but if a site id exists that matches the requested site id, that's what we will use if ((context != null) && (context.length() > 0)) { if (m_siteAlias && (m_aliasService != null) && (m_siteService != null) && (!m_siteService.siteExists(context))) { try { String target = m_aliasService.getTarget(context); // the code is taken and adapted from // org.sakaiproject.content.impl.BaseContentService // public boolean parseEntityReference(String reference, Reference ref) Reference targetRef = EntityManager.newReference(target); // for a site reference if (SiteService.APPLICATION_ID.equals(targetRef.getType())) { // use the ref's id, i.e. the site id context = targetRef.getId(); } // for mail archive reference // TODO: taken from MailArchiveService.APPLICATION_ID to (fake) reduce a dependency -ggolden else if ("sakai:mailarchive".equals(targetRef.getType())) { // use the ref's context as the site id context = targetRef.getContext(); } } catch (IdUnusedException noAlias) { } } siteContext = "/site/" + context; } decoded.setContext(siteContext); if (nextslash == lastslash) { decoded.setContainer(Entity.SEPARATOR); } else { decoded.setContainer(s.substring(nextslash, lastslash)); } String filename = s.substring(lastslash + 1); filename = filename.substring(0, filename.length() - ending.length()); int versionSeparator = filename.lastIndexOf("@"); if (versionSeparator != -1 && versionSeparator < filename.length() - 1) { try { Integer.parseInt(filename.substring(versionSeparator + 1)); decoded.setPage(filename.substring(0, versionSeparator)); decoded.setVersion(filename.substring(versionSeparator + 1)); } catch (NumberFormatException e) { decoded.setPage(filename); decoded.setVersion("-1"); } } else { decoded.setPage(filename); decoded.setVersion("-1"); } return decoded; } return null; } /** * @return Returns the accessURLStart. */ public String getAccessURLStart() { return accessURLStart; } /** * @param accessURLStart * The accessURLStart to set. */ public void setAccessURLStart(String accessURLStart) { this.accessURLStart = accessURLStart; } public boolean isAvailable() { if (!setup) { if (!experimental) { available = true; } else if (ServerConfigurationService.getBoolean("wiki.experimental", false)) { available = true; } else { available = false; } setup = true; } return available; } /** * {@inheritDoc} */ public String getHTML(Entity e) { if (isAvailable()) { if (feedFormat == null) return null; String url = e.getUrl(); // remove the "/access" prefix if ( url.startsWith("/access") ) { url = url.substring("/access".length()); } if (m_siteAlias && url.startsWith ("/wiki/site/")) { // the url format: /wiki/site/siteID/page int slashIndex = url.indexOf (Entity.SEPARATOR, "/wiki/site/".length()); if (slashIndex != -1) { String siteId = url.substring ("/wiki/site/".length(), slashIndex); String pageURL = url.substring (slashIndex); String localSpace = "/site/" + siteId; url = "/wiki" + NameHelper.aliasSpace (localSpace) + pageURL; } } return MessageFormat .format(feedFormat, new Object[] { url }); } return null; } /** * @return Returns the feedFormat. */ public String getFeedFormat() { return feedFormat; } /** * @param feedFormat * The feedFormat to set. */ public void setFeedFormat(String feedFormat) { this.feedFormat = feedFormat; } /** * @return Returns the experimental. */ public boolean getExperimental() { return experimental; } /** * @param experimental * The experimental to set. */ public void setExperimental(boolean experimental) { this.experimental = experimental; } }