org.theospi.portfolio.guidance.impl.GuidanceManagerImpl.java Source code

Java tutorial

Introduction

Here is the source code for org.theospi.portfolio.guidance.impl.GuidanceManagerImpl.java

Source

/**********************************************************************************
* $URL:https://source.sakaiproject.org/svn/osp/trunk/common/api-impl/src/java/org/theospi/portfolio/guidance/impl/GuidanceManagerImpl.java $
* $Id:GuidanceManagerImpl.java 9134 2006-05-08 20:28:42Z chmaurer@iupui.edu $
***********************************************************************************
*
 * Copyright (c) 2005, 2006, 2007, 2008 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.theospi.portfolio.guidance.impl;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jdom.CDATA;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.output.XMLOutputter;
import org.sakaiproject.authz.api.SecurityService;
import org.sakaiproject.content.api.ContentCollection;
import org.sakaiproject.content.api.ContentHostingService;
import org.sakaiproject.content.api.ContentResource;
import org.sakaiproject.content.api.ContentResourceEdit;
import org.sakaiproject.entity.api.EntityManager;
import org.sakaiproject.entity.api.Reference;
import org.sakaiproject.entity.api.ResourceProperties;
import org.sakaiproject.entity.api.ResourcePropertiesEdit;
import org.sakaiproject.exception.IdUnusedException;
import org.sakaiproject.exception.ServerOverloadException;
import org.sakaiproject.metaobj.shared.mgt.ContentEntityUtil;
import org.sakaiproject.metaobj.shared.mgt.IdManager;
import org.sakaiproject.metaobj.shared.model.Id;
import org.sakaiproject.metaobj.shared.model.MimeType;
import org.sakaiproject.metaobj.security.AllowMapSecurityAdvisor;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.theospi.portfolio.guidance.mgt.GuidanceManager;
import org.theospi.portfolio.guidance.model.Guidance;
import org.theospi.portfolio.guidance.model.GuidanceItem;
import org.theospi.portfolio.guidance.model.GuidanceItemAttachment;
import org.theospi.portfolio.security.AuthorizationFacade;

import java.io.*;
import java.util.*;
import java.util.zip.*;

/**
 * Created by IntelliJ IDEA.
 * User: John Ellis
 * Date: Nov 11, 2005
 * Time: 1:00:57 PM
 * To change this template use File | Settings | File Templates.
 */
public class GuidanceManagerImpl extends HibernateDaoSupport implements GuidanceManager {

    protected final Log logger = LogFactory.getLog(getClass());

    private AuthorizationFacade authorizationFacade;
    private SecurityService securityService;
    private EntityManager entityManager;
    private IdManager idManager;
    private ContentHostingService contentHostingService;

    public Guidance createNew(String description, String siteId, Id securityQualifier, String securityViewFunction,
            String securityEditFunction) {
        Guidance guidance = new Guidance(getIdManager().createId(), description, siteId, securityQualifier,
                securityViewFunction, securityEditFunction);
        /*
              GuidanceItem instruction = new GuidanceItem(guidance, Guidance.INSTRUCTION_TYPE);
              guidance.getItems().add(instruction);
            
              GuidanceItem example = new GuidanceItem(guidance, Guidance.EXAMPLE_TYPE);
              guidance.getItems().add(example);
            
              GuidanceItem rationale = new GuidanceItem(guidance, Guidance.RATIONALE_TYPE);
              guidance.getItems().add(rationale);
            
              GuidanceItem rubric = new GuidanceItem(guidance, Guidance.RUBRIC_TYPE);
              guidance.getItems().add(rubric);
                  
              GuidanceItem expectations = new GuidanceItem(guidance, Guidance.EXPECTATIONS_TYPE);
              guidance.getItems().add(expectations);
            */
        return guidance;
    }

    public Guidance getGuidance(Id guidanceId) {
        return getGuidance(guidanceId, true);
    }

    protected Guidance getGuidance(Id guidanceId, boolean checkAuthz) {
        Guidance guidance = (Guidance) getHibernateTemplate().get(Guidance.class, guidanceId);

        if (guidance == null) {
            return null;
        }

        if (guidance.getSecurityQualifier() != null && checkAuthz) {
            getAuthorizationFacade().checkPermission(guidance.getSecurityViewFunction(),
                    guidance.getSecurityQualifier());
        }

        if (assureAccess(guidance)) {
            getHibernateTemplate().save(guidance);
        }

        return guidance;
    }

    /**
     * Pushes the files in the guidance into the security bypass advisor thus allowing the 
     * files to be read.
     * @return boolean whether or not the guidance has been changed
     */
    public boolean assureAccess(Guidance guidance) {
        boolean changed = false;
        // setup access to the files
        List refs = new ArrayList();
        for (Iterator i = guidance.getItems().iterator(); i.hasNext();) {
            GuidanceItem item = (GuidanceItem) i.next();
            for (Iterator j = item.getAttachments().iterator(); j.hasNext();) {
                GuidanceItemAttachment attachment = (GuidanceItemAttachment) j.next();
                if (checkAttachment(attachment)) {
                    refs.add(attachment.getBaseReference().getBase().getReference());
                } else {
                    j.remove();
                    String guidanceText = item.getText();
                    int fileLocation = -1;

                    String encodedRef = attachment.getBaseReference().getBase().getReference();
                    encodedRef = encodedRef.replaceAll(" ", "%20");
                    do {
                        fileLocation = guidanceText.indexOf(encodedRef);
                        if (fileLocation >= 0) {
                            int startChar = guidanceText.lastIndexOf("<a", fileLocation);
                            int lastChar = guidanceText.indexOf("</a", fileLocation);
                            lastChar = guidanceText.indexOf(">", lastChar) + 1;
                            guidanceText = guidanceText.substring(0, startChar) + "--File Deleted--"
                                    + guidanceText.substring(lastChar);
                        }
                    } while (fileLocation > 0);
                    item.setText(guidanceText);

                    changed = true;
                }
            }
        }

        getSecurityService()
                .pushAdvisor(new AllowMapSecurityAdvisor(ContentHostingService.EVENT_RESOURCE_READ, refs));

        return changed;
    }

    /**
     * This checks for the existance of a resource in a non-permission checking way.
     * If there isn't a uuid for a resource or there isn't a resolved id then it doesn't exist
     * @param attachment
     * @return boolean true if a resource exists, false if it does not
     */
    protected boolean checkAttachment(GuidanceItemAttachment attachment) {
        String id = attachment.getBaseReference().getBase().getId();

        String uuid = getContentHostingService().getUuid(id);
        if (uuid == null)
            return false;
        return getContentHostingService().resolveUuid(uuid) != null;
    }

    public Guidance saveGuidance(Guidance guidance) {
        if (guidance.isNewObject()) {
            guidance.setNewId(guidance.getId());
            guidance.setId(null);
            getHibernateTemplate().save(guidance);
            guidance.setNewObject(false);
        } else {
            getHibernateTemplate().saveOrUpdate(guidance);
        }

        return guidance;
    }

    public void deleteGuidance(Guidance guidance) {
        getHibernateTemplate().delete(guidance);
    }

    public Reference decorateReference(Guidance guidance, String reference) {
        String fullRef = ContentEntityUtil.getInstance().buildRef(GuidanceEntityProducer.GUIDANCE_PRODUCER,
                guidance.getSiteId(), guidance.getId().getValue(), reference);

        return getEntityManager().newReference(fullRef);
    }

    public List listGuidances(String siteId) {
        return getHibernateTemplate().findByNamedQuery("listGuidancesBySite", siteId);
    }

    public Guidance getGuidance(String id) {
        return getGuidance(id, true);
    }

    public Guidance getGuidance(String id, boolean checkAuthz) {
        return getGuidance(getIdManager().getId(id), checkAuthz);
    }

    public void packageGuidanceForExport(List guidanceIds, OutputStream os) throws IOException {
        CheckedOutputStream checksum = new CheckedOutputStream(os, new Adler32());
        ZipOutputStream zos = new ZipOutputStream(new BufferedOutputStream(checksum));
        List exportedRefs = new ArrayList();
        for (Iterator i = guidanceIds.iterator(); i.hasNext();) {
            String id = (String) i.next();
            processGuidance(id, zos, exportedRefs);
        }

        zos.finish();
        zos.flush();
    }

    protected void processGuidance(String guidanceId, ZipOutputStream zos, List exportedRefs) throws IOException {
        Guidance guidance = getGuidance(guidanceId);
        for (Iterator i = guidance.getItems().iterator(); i.hasNext();) {
            GuidanceItem item = (GuidanceItem) i.next();
            try {
                processItem(zos, item, exportedRefs);
            } catch (ServerOverloadException e) {
                throw new RuntimeException(e);
            }
        }

        ZipEntry definitionFile = new ZipEntry("guidance-" + guidanceId + ".xml");
        zos.putNextEntry(definitionFile);
        Document doc = createGuidanceAsXml(guidance);
        String docStr = (new XMLOutputter()).outputString(doc);
        zos.write(docStr.getBytes("UTF-8"));
        zos.closeEntry();
    }

    protected void processItem(ZipOutputStream zos, GuidanceItem item, List exportedRefs)
            throws IOException, ServerOverloadException {
        for (Iterator i = item.getAttachments().iterator(); i.hasNext();) {
            GuidanceItemAttachment attachment = (GuidanceItemAttachment) i.next();
            if (!exportedRefs.contains(attachment.getBaseReference().getBase().getReference())) {
                processAttachment(zos, attachment);
                exportedRefs.add(attachment.getBaseReference().getBase().getReference());
            }
        }
    }

    protected void processAttachment(ZipOutputStream zos, GuidanceItemAttachment attachment)
            throws ServerOverloadException, IOException {
        ContentResource entity = (ContentResource) attachment.getBaseReference().getBase().getEntity();

        String newName = entity.getProperties().getProperty(entity.getProperties().getNamePropDisplayName());
        String cleanedName = newName.substring(newName.lastIndexOf('\\') + 1);
        String entryName = "attachments/" + entity.getContentType() + "/" + getAttachmentRefHash(attachment) + "/"
                + cleanedName;

        storeFileInZip(zos, entity.streamContent(), entryName);
    }

    protected int getAttachmentRefHash(GuidanceItemAttachment attachment) {
        return attachment.getBaseReference().getBase().getReference().hashCode();
    }

    protected void storeFileInZip(ZipOutputStream zos, InputStream in, String entryName) throws IOException {

        byte data[] = new byte[1024 * 10];

        if (File.separatorChar == '\\') {
            entryName = entryName.replace('\\', '/');
        }

        ZipEntry newfileEntry = new ZipEntry(entryName);

        zos.putNextEntry(newfileEntry);

        BufferedInputStream origin = new BufferedInputStream(in, data.length);

        int count;
        while ((count = origin.read(data, 0, data.length)) != -1) {
            zos.write(data, 0, count);
        }
        zos.closeEntry();
        in.close();
    }

    protected Document createGuidanceAsXml(Guidance guidance) {
        Element rootNode = new Element("guidance");

        rootNode.setAttribute("formatVersion", "2.1");
        addNode(rootNode, "id", guidance.getId().getValue());
        addNode(rootNode, "description", guidance.getDescription());
        addNode(rootNode, "securityEditFunction", guidance.getSecurityEditFunction());
        addNode(rootNode, "securityViewFunction", guidance.getSecurityViewFunction());
        Element items = new Element("items");

        for (Iterator i = guidance.getItems().iterator(); i.hasNext();) {
            GuidanceItem item = (GuidanceItem) i.next();
            addItem(items, item);
        }

        rootNode.addContent(items);

        return new Document(rootNode);
    }

    protected void addItem(Element items, GuidanceItem item) {
        Element itemElement = new Element("item");

        addNode(itemElement, "type", item.getType());
        addNode(itemElement, "text", item.getText());

        Element attachments = new Element("attachments");

        for (Iterator i = item.getAttachments().iterator(); i.hasNext();) {
            GuidanceItemAttachment attachment = (GuidanceItemAttachment) i.next();
            addAttachment(attachments, attachment);
        }
        itemElement.addContent(attachments);
        items.addContent(itemElement);
    }

    protected void addAttachment(Element attachments, GuidanceItemAttachment attachment) {
        Element attachmentElement = new Element("attachment");
        addNode(attachmentElement, "ref", attachment.getBaseReference().getBase().getReference());
        addNode(attachmentElement, "url", attachment.getFullReference().getBase().getUrl());
        attachments.addContent(attachmentElement);
    }

    protected void addNode(Element parentNode, String name, String value) {
        Element attrNode = new Element(name);
        attrNode.addContent(new CDATA(value));
        parentNode.addContent(attrNode);
    }

    /**
     * This function is up to spec but incomplete.  The guidance security qualifier
     * needs to be set on these objects so they can be retrieved.
     * 
     * @param parent the parent resource folder where attachments go
     * @param siteId the site which will recieve the imported "stuff"
     * @param in  The Input stream representing the output stream of the export
     * @return Map contains a map with keys being of type String as old Ids and the 
     * values as being the Guidance object
     */
    public Map importGuidanceList(ContentCollection parent, String siteId, InputStream in) throws IOException {
        Map guidanceMap = new Hashtable();
        ZipInputStream zis = new ZipInputStream(in);
        ZipEntry currentEntry = zis.getNextEntry();

        Map attachmentMap = new Hashtable();

        while (currentEntry != null) {
            if (!currentEntry.isDirectory()) {
                if (currentEntry.getName().startsWith("guidance-")) {
                    importGuidance(siteId, zis, guidanceMap);
                } else if (currentEntry.getName().startsWith("attachments/")) {
                    importAttachmentRef(parent, currentEntry, siteId, zis, attachmentMap);
                }
            }

            zis.closeEntry();
            currentEntry = zis.getNextEntry();
        }

        postPocessAttachments(guidanceMap.values(), attachmentMap);

        for (Iterator i = guidanceMap.values().iterator(); i.hasNext();) {
            Guidance guidance = (Guidance) i.next();
            saveGuidance(guidance);
        }

        return guidanceMap;
    }

    protected void postPocessAttachments(Collection guidances, Map attachmentMap) {
        for (Iterator i = guidances.iterator(); i.hasNext();) {
            Guidance guidance = (Guidance) i.next();
            postProcessGuidance(guidance, attachmentMap);
        }
    }

    protected void postProcessGuidance(Guidance guidance, Map attachmentMap) {
        for (Iterator i = guidance.getItems().iterator(); i.hasNext();) {
            GuidanceItem item = (GuidanceItem) i.next();
            postProcessGuidanceItem(item, attachmentMap);
        }
    }

    protected void postProcessGuidanceItem(GuidanceItem item, Map attachmentMap) {
        List guidanceAttachments = new ArrayList();

        for (Iterator i = item.getAttachments().iterator(); i.hasNext();) {
            AttachmentImportWrapper wrapper = (AttachmentImportWrapper) i.next();
            Reference baseRef = getEntityManager()
                    .newReference((String) attachmentMap.get("" + wrapper.getOldRef().hashCode()));
            Reference fullRef = decorateReference(item.getGuidance(), baseRef.getReference());
            GuidanceItemAttachment newAttachment = new GuidanceItemAttachment(item, baseRef, fullRef);
            item.setText(substitueText(wrapper.getOldUrl(), newAttachment, item.getText()));
            guidanceAttachments.add(newAttachment);
        }

        item.setAttachments(guidanceAttachments);
    }

    protected String substitueText(String oldUrl, GuidanceItemAttachment newAttachment, String text) {
        return text.replaceAll(oldUrl, newAttachment.getFullReference().getBase().getUrl());
    }

    protected void importAttachmentRef(ContentCollection fileParent, ZipEntry currentEntry, String siteId,
            ZipInputStream zis, Map attachmentMap) {
        File file = new File(currentEntry.getName());

        MimeType mimeType = new MimeType(file.getParentFile().getParentFile().getParentFile().getName(),
                file.getParentFile().getParentFile().getName());

        String contentType = mimeType.getValue();

        String oldId = file.getParentFile().getName();

        try {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            int c = zis.read();

            while (c != -1) {
                bos.write(c);
                c = zis.read();
            }

            String fileId = fileParent.getId() + file.getName();
            ContentResource rez = null;
            try {
                rez = getContentHostingService().getResource(fileId);
            } catch (IdUnusedException iduue) {
                logger.info(iduue);
            }
            if (rez == null) {
                ContentResourceEdit resource = getContentHostingService().addResource(fileId);
                ResourcePropertiesEdit resourceProperties = resource.getPropertiesEdit();
                resourceProperties.addProperty(ResourceProperties.PROP_DISPLAY_NAME, file.getName());
                resource.setContent(bos.toByteArray());
                resource.setContentType(contentType);
                getContentHostingService().commitResource(resource);
                rez = resource;
            }
            attachmentMap.put(oldId, rez.getReference());
        } catch (Exception exp) {
            throw new RuntimeException(exp);
        }
    }

    protected void importGuidance(String siteId, InputStream is, Map guidanceMap) throws IOException {
        SAXBuilder builder = new SAXBuilder();
        builder.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); // SAK-23131
        Document document = null;

        byte[] bytes = readStreamToBytes(is);

        try {
            document = builder.build(new ByteArrayInputStream(bytes));
        } catch (JDOMException e) {
            throw new RuntimeException(e);
        }
        Element docRoot = document.getRootElement();

        Id oldGuidanceId = getIdManager().getId(docRoot.getChildText("id"));
        String description = docRoot.getChildText("description");
        String viewFunc = docRoot.getChildText("securityViewFunction");
        String editFunc = docRoot.getChildText("securityEditFunction");

        Guidance guidance = new Guidance(getIdManager().createId(), description, siteId, null, viewFunc, editFunc);

        List itemElements = docRoot.getChild("items").getChildren("item");
        List items = new ArrayList();
        for (Iterator i = itemElements.iterator(); i.hasNext();) {
            items.add(importItem(guidance, (Element) i.next()));
        }
        guidance.setItems(items);
        guidanceMap.put(oldGuidanceId.getValue(), guidance);
    }

    protected byte[] readStreamToBytes(InputStream inStream) throws IOException {
        ByteArrayOutputStream bytes = new ByteArrayOutputStream();
        byte data[] = new byte[10 * 1024];

        int count;
        while ((count = inStream.read(data, 0, 10 * 1024)) != -1) {
            bytes.write(data, 0, count);
        }
        byte[] tmp = bytes.toByteArray();
        bytes.close();
        return tmp;
    }

    protected GuidanceItem importItem(Guidance guidance, Element element) {
        String type = element.getChildText("type");
        GuidanceItem item = new GuidanceItem(guidance, type);
        item.setText(element.getChildText("text"));

        List attachmentElements = element.getChild("attachments").getChildren("attachment");
        List attachments = new ArrayList();
        for (Iterator i = attachmentElements.iterator(); i.hasNext();) {
            attachments.add(importAttachment(item, (Element) i.next()));
        }
        item.setAttachments(attachments);

        return item;
    }

    protected AttachmentImportWrapper importAttachment(GuidanceItem item, Element element) {
        return new AttachmentImportWrapper(element.getChildText("ref"), element.getChildText("url"));
    }

    /**
     * Pulls all Guidance
     * @return List of Guidance
     */
    public List getGuidanceForWarehousing() {
        List guidance = getHibernateTemplate().findByNamedQuery("listGuidances");

        for (Iterator i = guidance.iterator(); i.hasNext();) {
            Guidance w = (Guidance) i.next();
        }

        return guidance;
    }

    public AuthorizationFacade getAuthorizationFacade() {
        return authorizationFacade;
    }

    public void setAuthorizationFacade(AuthorizationFacade authorizationFacade) {
        this.authorizationFacade = authorizationFacade;
    }

    public SecurityService getSecurityService() {
        return securityService;
    }

    public void setSecurityService(SecurityService securityService) {
        this.securityService = securityService;
    }

    public EntityManager getEntityManager() {
        return entityManager;
    }

    public void setEntityManager(EntityManager entityManager) {
        this.entityManager = entityManager;
    }

    public IdManager getIdManager() {
        return idManager;
    }

    public void setIdManager(IdManager idManager) {
        this.idManager = idManager;
    }

    public ContentHostingService getContentHostingService() {
        return contentHostingService;
    }

    public void setContentHostingService(ContentHostingService contentHostingService) {
        this.contentHostingService = contentHostingService;
    }
}