/********************************************************************************** * $URL: https://source.sakaiproject.org/svn/rwiki/trunk/rwiki-impl/impl/src/java/uk/ac/cam/caret/sakai/rwiki/component/model/impl/RWikiEntityImpl.java $ * $Id: RWikiEntityImpl.java 84222 2010-11-03 13:15:52Z david.horwitz@uct.ac.za $ *********************************************************************************** * * 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.model.impl; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.util.Date; import java.util.Stack; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.xerces.impl.dv.util.Base64; import org.sakaiproject.component.cover.ServerConfigurationService; import org.sakaiproject.entity.api.Reference; import org.sakaiproject.entity.api.ResourceProperties; import org.sakaiproject.util.BaseResourceProperties; import org.w3c.dom.CDATASection; import org.w3c.dom.CharacterData; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import uk.ac.cam.caret.sakai.rwiki.service.api.RWikiObjectService; import uk.ac.cam.caret.sakai.rwiki.service.api.model.RWikiEntity; import uk.ac.cam.caret.sakai.rwiki.service.api.model.RWikiObject; import uk.ac.cam.caret.sakai.rwiki.utils.NameHelper; import uk.ac.cam.caret.sakai.rwiki.utils.SchemaNames; public class RWikiEntityImpl implements RWikiEntity { private static Log log = LogFactory.getLog(RWikiEntityImpl.class); public static final String RW_ID = "id"; // I dont think that content is a propertyrp.addProperty("content", // this.getContent()); private RWikiObject rwo = null; private Reference reference = null; public RWikiEntityImpl(RWikiObject rwo) { this.rwo = rwo; } public RWikiEntityImpl(Reference ref) { this.reference = ref; } /** * {@inheritDoc} */ public ResourceProperties getProperties() { if (rwo == null) { ResourceProperties rp = new BaseResourceProperties(); rp.addProperty(RWikiEntity.RP_REALM, reference.getContext() + reference.getContainer()); rp.addProperty(RWikiEntity.RP_REALM, reference.getId()); rp.addProperty(RWikiEntity.RP_CONTAINER, "true"); return rp; } else { ResourceProperties rp = new BaseResourceProperties(); rp.addProperty("id", this.getId()); // I dont think that content is a propertyrp.addProperty("content", // this.getContent()); rp.addProperty(RWikiEntity.RP_NAME, rwo.getName()); rp.addProperty(RWikiEntity.RP_OWNER, rwo.getOwner()); rp.addProperty(RWikiEntity.RP_REALM, rwo.getRealm()); rp.addProperty(RWikiEntity.RP_REFERENCED, rwo.getReferenced()); rp.addProperty(RWikiEntity.RP_RWID, rwo.getRwikiobjectid()); rp.addProperty(RWikiEntity.RP_SHA1, rwo.getSha1()); rp.addProperty(RWikiEntity.RP_USER, rwo.getUser()); rp.addProperty(RWikiEntity.RP_GROUP_ADMIN, String.valueOf(rwo .getGroupAdmin())); rp.addProperty(RWikiEntity.RP_GROUP_READ, String.valueOf(rwo .getGroupRead())); rp.addProperty(RWikiEntity.RP_GROUP_WRITE, String.valueOf(rwo .getGroupWrite())); rp.addProperty(RWikiEntity.RP_OWNER_ADMIN, String.valueOf(rwo .getOwnerAdmin())); rp.addProperty(RWikiEntity.RP_OWNER_READ, String.valueOf(rwo .getOwnerRead())); rp.addProperty(RWikiEntity.RP_OWNER_WRITE, String.valueOf(rwo .getOwnerWrite())); rp.addProperty(RWikiEntity.RP_PUBLIC_READ, String.valueOf(rwo .getPublicRead())); rp.addProperty(RWikiEntity.RP_PUBLIC_WRITE, String.valueOf(rwo .getPublicWrite())); rp.addProperty(RWikiEntity.RP_REVISION, String.valueOf(rwo .getRevision())); rp.addProperty(RWikiEntity.RP_VERSION, String.valueOf(rwo .getVersion().getTime())); rp.addProperty(RWikiEntity.RP_CONTAINER, "false"); return rp; } } /** * {@inheritDoc} */ public String getReference() { if (rwo == null) return RWikiObjectService.REFERENCE_ROOT + reference.getId() + "."; return RWikiObjectService.REFERENCE_ROOT + rwo.getName() + "."; } /** * {@inheritDoc} */ public String getUrl() { if (rwo == null) { return RWikiObjectService.REFERENCE_ROOT + encode(reference.getId()) + "."; } else { // /wiki access url return RWikiObjectService.REFERENCE_ROOT + encode(rwo.getName()) + "."; } } private String encode(String toEncode) { try { String encoded = URLEncoder.encode(toEncode, "UTF-8"); encoded = encoded.replaceAll("\\+", "%20").replaceAll("%2F", "/"); return encoded; } catch (UnsupportedEncodingException e) { throw new IllegalStateException("UTF-8 Encoding is not supported when encoding: " + toEncode + ": " + e.getMessage()); } } /** * {@inheritDoc} */ public Element toXml(Document doc, Stack stack) { if (rwo == null) throw new RuntimeException( " Cant serialise containers at the moment "); Element wikipage = doc.createElement(SchemaNames.EL_WIKIPAGE); if (stack.isEmpty()) { doc.appendChild(wikipage); } else { ((Element) stack.peek()).appendChild(wikipage); } stack.push(wikipage); wikipage.setAttribute(SchemaNames.ATTR_ID, rwo.getId()); wikipage.setAttribute(SchemaNames.ATTR_PAGE_NAME, rwo.getName()); wikipage.setAttribute(SchemaNames.ATTR_REVISION, String.valueOf(rwo .getRevision())); wikipage.setAttribute(SchemaNames.ATTR_USER, rwo.getUser()); wikipage.setAttribute(SchemaNames.ATTR_OWNER, rwo.getOwner()); // I would like to be able to render this, but we cant... because its a // pojo ! getProperties().toXml(doc, stack); Element content = doc.createElement(SchemaNames.EL_WIKICONTENT); stack.push(content); wikipage.appendChild(content); content.setAttribute("enc", "BASE64"); try { String b64Content = Base64.encode(rwo.getContent() .getBytes("UTF-8")); CDATASection t = doc.createCDATASection(b64Content); stack.push(t); content.appendChild(t); stack.pop(); } catch (UnsupportedEncodingException usex) { // if UTF-8 isnt available, we are in big trouble ! throw new IllegalStateException("Cannot find Encoding UTF-8"); } stack.pop(); stack.pop(); return wikipage; } /** * {@inheritDoc} */ public void fromXml(Element el, String defaultRealm) throws Exception { if (rwo == null) throw new RuntimeException( " Cant deserialise containers at the moment "); NodeList nl = el.getElementsByTagName("properties"); // this is hard coded in BaseResourceProperties the element name // properties if (nl == null || nl.getLength() != 1) throw new Exception("Cant find a properties element in " + el.getNodeName() + " id: " + el.getAttribute(SchemaNames.ATTR_ID) + " pagename: " + el.getAttribute(SchemaNames.ATTR_PAGE_NAME)); // only take the first properties Element properties = (Element) nl.item(0); ResourceProperties rp = new BaseResourceProperties(properties); nl = el.getElementsByTagName(SchemaNames.EL_WIKICONTENT); if (nl == null || nl.getLength() != 1) throw new Exception("Cant find a wikiproperties element in " + el.getNodeName() + " id: " + el.getAttribute(SchemaNames.ATTR_ID) + " pagename: " + el.getAttribute(SchemaNames.ATTR_PAGE_NAME)); // only accpet the first Element wikiContents = (Element) nl.item(0); nl = wikiContents.getChildNodes(); StringBuffer content = new StringBuffer(); for (int i = 0; i < nl.getLength(); i++) { Node n = nl.item(i); if (n instanceof CharacterData) { CharacterData cdnode = (CharacterData) n; try { content.append(new String(Base64.decode(cdnode.getData()), "UTF-8")); } catch (Throwable t) { log.warn("Cant decode node content for " + cdnode); } } } String realm = rp.getProperty(RWikiEntity.RP_REALM); rwo.setId(rp.getProperty(RWikiEntity.RP_ID)); rwo.setName(NameHelper.globaliseName(NameHelper.localizeName(rp .getProperty(RWikiEntity.RP_NAME), realm), defaultRealm)); rwo.setOwner(rp.getProperty(RWikiEntity.RP_OWNER)); rwo.setRealm(defaultRealm); rwo.setReferenced(rp.getProperty(RWikiEntity.RP_REFERENCED)); // rwo.setRwikiobjectid(rp.getProperty("rwid")); rwo.setContent(content.toString()); if (!rwo.getSha1().equals(rp.getProperty(RWikiEntity.RP_SHA1))) throw new Exception("Sha Checksum Missmatch on content " + rp.getProperty(RWikiEntity.RP_SHA1) + " != " + rwo.getSha1()); rwo.setUser(rp.getProperty(RWikiEntity.RP_USER)); rwo.setGroupAdmin(rp.getBooleanProperty(RWikiEntity.RP_GROUP_ADMIN)); rwo.setGroupRead(rp.getBooleanProperty(RWikiEntity.RP_GROUP_READ)); rwo.setGroupWrite(rp.getBooleanProperty(RWikiEntity.RP_GROUP_WRITE)); rwo.setOwnerAdmin(rp.getBooleanProperty(RWikiEntity.RP_OWNER_ADMIN)); rwo.setOwnerRead(rp.getBooleanProperty(RWikiEntity.RP_OWNER_READ)); rwo.setOwnerWrite(rp.getBooleanProperty(RWikiEntity.RP_OWNER_WRITE)); rwo.setPublicRead(rp.getBooleanProperty(RWikiEntity.RP_PUBLIC_READ)); rwo.setPublicWrite(rp.getBooleanProperty(RWikiEntity.RP_PUBLIC_WRITE)); rwo.setRevision(Integer.valueOf(rp.getProperty(RWikiEntity.RP_REVISION))); rwo.setVersion(new Date(rp.getLongProperty(RWikiEntity.RP_VERSION))); } /** * @inheritDoc */ public String getReference(String rootProperty) { return getReference(); } /** * @inheritDoc */ public String getUrl(String rootProperty) { return getUrl(); } /** * {@inheritDoc} */ public String getId() { if (rwo == null) return reference.getId(); return rwo.getId(); } /** * {@inheritDoc} */ public RWikiObject getRWikiObject() { if (rwo == null) throw new RuntimeException( "RWiki Containers dont have objects attached "); return rwo; } public boolean isContainer() { return (rwo == null); } }