/**********************************************************************************
* $URL: https://source.sakaiproject.org/svn/metaobj/trunk/metaobj-util/tool-lib/src/java/org/sakaiproject/metaobj/shared/control/AddStructuredArtifactDefinitionController.java $
* $Id: AddStructuredArtifactDefinitionController.java 130481 2013-10-15 17:36:54Z dsobiera@indiana.edu $
***********************************************************************************
*
* Copyright (c) 2004, 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.sakaiproject.metaobj.shared.control;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Hashtable;
import java.io.InputStream;
import org.sakaiproject.authz.api.SecurityAdvisor;
import org.sakaiproject.authz.cover.SecurityService;
import org.sakaiproject.component.cover.ComponentManager;
import org.sakaiproject.content.api.ContentHostingService;
import org.sakaiproject.content.api.ContentResource;
import org.sakaiproject.content.api.FilePickerHelper;
import org.sakaiproject.entity.api.Reference;
import org.sakaiproject.exception.IdUnusedException;
import org.sakaiproject.exception.PermissionException;
import org.sakaiproject.exception.TypeException;
import org.sakaiproject.metaobj.security.AuthorizationFailedException;
import org.sakaiproject.metaobj.shared.SharedFunctionConstants;
import org.sakaiproject.metaobj.shared.FormHelper;
import org.sakaiproject.metaobj.shared.mgt.StructuredArtifactDefinitionManager;
import org.sakaiproject.metaobj.shared.model.Id;
import org.sakaiproject.metaobj.shared.model.PersistenceException;
import org.sakaiproject.metaobj.shared.model.StructuredArtifactDefinitionBean;
import org.sakaiproject.metaobj.utils.mvc.intf.CustomCommandController;
import org.sakaiproject.metaobj.utils.mvc.intf.FormController;
import org.sakaiproject.metaobj.utils.mvc.intf.LoadObjectController;
import org.sakaiproject.tool.api.SessionManager;
import org.sakaiproject.tool.api.ToolSession;
import org.sakaiproject.tool.cover.ToolManager;
import org.sakaiproject.util.FormattedText;
import org.springframework.validation.Errors;
import org.springframework.web.servlet.ModelAndView;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.URIResolver;
import javax.xml.transform.stream.StreamSource;
/**
* @author chmaurer
*/
public class AddStructuredArtifactDefinitionController extends AbstractStructuredArtifactDefinitionController
implements CustomCommandController, FormController, LoadObjectController {
private SessionManager sessionManager;
private ContentHostingService contentHosting;
private TransformerFactory transformerFactory;
private URIResolver uriResolver;
public Object formBackingObject(Map request, Map session, Map application) {
//check to see if you have create permissions
checkPermission(SharedFunctionConstants.CREATE_ARTIFACT_DEF);
StructuredArtifactDefinitionBean backingObject = new StructuredArtifactDefinitionBean();
backingObject.setOwner(getAuthManager().getAgent());
return backingObject;
}
public Object fillBackingObject(Object incomingModel, Map request, Map session, Map application) throws Exception {
if (session.get(StructuredArtifactDefinitionManager.SAD_SESSION_TAG) != null) {
return session.remove(StructuredArtifactDefinitionManager.SAD_SESSION_TAG);
}
else {
return incomingModel;
}
}
public ModelAndView handleRequest(Object requestModel, Map request,
Map session, Map application, Errors errors) {
StructuredArtifactDefinitionBean sad = (StructuredArtifactDefinitionBean) requestModel;
if (StructuredArtifactDefinitionValidator.PICK_SCHEMA_ACTION.equals(sad.getFilePickerAction()) ||
StructuredArtifactDefinitionValidator.PICK_TRANSFORM_ACTION.equals(sad.getFilePickerAction()) ||
StructuredArtifactDefinitionValidator.PICK_ALTCREATEXSLT_ACTION.equals(sad.getFilePickerAction()) ||
StructuredArtifactDefinitionValidator.PICK_ALTVIEWXSLT_ACTION.equals(sad.getFilePickerAction())) {
session.put(StructuredArtifactDefinitionManager.SAD_SESSION_TAG, sad);
//set the filter for xsl files since it is 3 out of 4 cases
session.put(FilePickerHelper.FILE_PICKER_RESOURCE_FILTER,
ComponentManager.get("org.sakaiproject.content.api.ContentResourceFilter.metaobjFile.xsl"));
if (StructuredArtifactDefinitionValidator.PICK_SCHEMA_ACTION.equals(sad.getFilePickerAction())) {
//set the filter for xsd files only in this case
session.put(FilePickerHelper.FILE_PICKER_RESOURCE_FILTER,
ComponentManager.get("org.sakaiproject.content.api.ContentResourceFilter.metaobjFile"));
session.put(FilePickerHelper.FILE_PICKER_TITLE_TEXT, getMessage("text_selectXSD"));
session.put(FilePickerHelper.FILE_PICKER_INSTRUCTION_TEXT, getMessage("text_selectXSD_instructions"));
}
session.put(FilePickerHelper.FILE_PICKER_MAX_ATTACHMENTS, new Integer(1));
List files = new ArrayList();
if (StructuredArtifactDefinitionValidator.PICK_ALTCREATEXSLT_ACTION.equals(sad.getFilePickerAction())) {
if (sad.getAlternateCreateXslt() != null) {
String id = getContentHosting().resolveUuid(sad.getAlternateCreateXslt().getValue());
Reference ref = getEntityManager().newReference(getContentHosting().getReference(id));
files.add(ref);
}
session.put(FilePickerHelper.FILE_PICKER_ATTACHMENTS, files);
session.put(FilePickerHelper.FILE_PICKER_TITLE_TEXT, getMessage("text_selectAltCreateXsl"));
session.put(FilePickerHelper.FILE_PICKER_INSTRUCTION_TEXT, getMessage("text_selectAltCreateXsl_instructions"));
}
else if (StructuredArtifactDefinitionValidator.PICK_ALTVIEWXSLT_ACTION.equals(sad.getFilePickerAction())) {
if (sad.getAlternateViewXslt() != null) {
String id = getContentHosting().resolveUuid(sad.getAlternateViewXslt().getValue());
Reference ref = getEntityManager().newReference(getContentHosting().getReference(id));
files.add(ref);
}
session.put(FilePickerHelper.FILE_PICKER_ATTACHMENTS, files);
session.put(FilePickerHelper.FILE_PICKER_TITLE_TEXT, getMessage("text_selectAltViewXsl"));
session.put(FilePickerHelper.FILE_PICKER_INSTRUCTION_TEXT, getMessage("text_selectAltViewXsl_instructions"));
}
return new ModelAndView("pickSchema");
}
if (request.get("systemOnly") == null) {
sad.setSystemOnly(false);
}
if (sad.getSchemaFile() != null) {
try {
getStructuredArtifactDefinitionManager().validateSchema(sad);
}
catch (Exception e) {
logger.warn("", e);
String errorMessage = "error reading schema file: " + e.getMessage();
sad.setSchemaFile(null);
errors.rejectValue("schemaFile", "schema_file_error",
new Object[]{e.getMessage()}, errorMessage);
}
}
if (sad.getAlternateCreateXslt() != null) {
if (!validateXslt(sad.getAlternateCreateXslt(), "alternateCreateXslt", errors)) {
sad.setAlternateCreateXslt(null);
sad.setAlternateCreateXsltName(null);
}
}
if (sad.getAlternateViewXslt() != null) {
if (!validateXslt(sad.getAlternateViewXslt(), "alternateViewXslt", errors)) {
sad.setAlternateViewXslt(null);
sad.setAlternateViewXsltName(null);
}
}
if (sad.getInstruction() != null) {
StringBuilder htmlErrors = new StringBuilder();
String newText = FormattedText.processFormattedText(sad.getInstruction(), htmlErrors);
if (htmlErrors.length() > 0) {
errors.rejectValue("instruction", "instruction_error",
new Object[]{htmlErrors.toString()}, htmlErrors.toString());
}
else {
sad.setInstruction(newText);
}
}
if (errors.hasErrors()) {
return new ModelAndView("failure");
}
if ("preview".equals(request.get("previewAction"))) {
session.put(StructuredArtifactDefinitionManager.SAD_SESSION_TAG, sad);
session.put(FormHelper.PREVIEW_HOME_TAG, sad);
return new ModelAndView("preview");
}
try {
if (!getStructuredArtifactDefinitionManager().isGlobal()) {
sad.setSiteId(getWorksiteManager().getCurrentWorksiteId().getValue());
}
save(sad, errors);
}
catch (AuthorizationFailedException e) {
throw e;
}
catch (PersistenceException e) {
errors.rejectValue(e.getField(), e.getErrorCode(), e.getErrorInfo(),
e.getDefaultMessage());
}
catch (Exception e) {
logger.warn("", e);
String errorMessage = "error transforming or saving artifacts: " + e.getMessage();
errors.rejectValue("xslConversionFileId", errorMessage, errorMessage);
sad.setXslConversionFileId(null);
return new ModelAndView("failure");
}
if (errors.getErrorCount() > 0) {
return new ModelAndView("failure");
}
Map model = new Hashtable();
model.put("newFormId", sad.getId().getValue());
return new ModelAndView("success", model); //prepareListView(request, sad.getId().getValue());
}
protected boolean validateXslt(Id xsltResource, String field, Errors errors) {
try {
Boolean canEdit = getAuthzManager().isAuthorized(SharedFunctionConstants.EDIT_ARTIFACT_DEF,
getIdManager().getId(ToolManager.getCurrentPlacement().getId()));
if (canEdit != null && canEdit) {
String id = getContentHosting().resolveUuid(xsltResource.getValue());
String ref = getContentHosting().getReference(id);
SecurityService.pushAdvisor(new LocalSecurityAdvisor(getAuthManager().getAgent().getId().getValue(), "content.read", ref));
}
ContentResource resource = getContentResource(xsltResource, canEdit);
InputStream is = resource.streamContent();
getTransformerFactory().newTransformer(new StreamSource(is));
if (canEdit != null && canEdit) {
SecurityService.popAdvisor();
}
return true;
}
catch (Exception e) {
logger.warn("", e);
String errorMessage = "error validating xslt file: " + e.getMessage();
errors.rejectValue(field, "render_file_error",
new Object[]{e.getMessage()}, errorMessage);
}
return false;
}
protected void save(StructuredArtifactDefinitionBean sad, Errors errors) {
//check to see if you have create permissions
checkPermission(SharedFunctionConstants.CREATE_ARTIFACT_DEF);
getStructuredArtifactDefinitionManager().save(sad);
}
public Map referenceData(Map request, Object command, Errors errors) {
Map base = super.referenceData(request, command, errors);
StructuredArtifactDefinitionBean sad = (StructuredArtifactDefinitionBean) command;
ToolSession session = getSessionManager().getCurrentToolSession();
if (session.getAttribute(FilePickerHelper.FILE_PICKER_CANCEL) == null &&
session.getAttribute(FilePickerHelper.FILE_PICKER_ATTACHMENTS) != null) {
// here is where we setup the id
List refs = (List) session.getAttribute(FilePickerHelper.FILE_PICKER_ATTACHMENTS);
Id nodeId = null;
Id nodeUuid = null;
String nodeName = "";
if (refs != null && refs.size() > 0) {
Reference ref = (Reference) refs.get(0);
nodeId = getIdManager().getId(ref.getId());
nodeUuid = getIdManager().getId(getContentHosting().getUuid(ref.getId()));
nodeName = ref.getProperties().getProperty(ref.getProperties().getNamePropDisplayName());
}
if (StructuredArtifactDefinitionValidator.PICK_SCHEMA_ACTION.equals(sad.getFilePickerAction())) {
sad.setSchemaFile(nodeId);
sad.setSchemaFileName(nodeName);
}
else if (StructuredArtifactDefinitionValidator.PICK_ALTCREATEXSLT_ACTION.equals(sad.getFilePickerAction())) {
sad.setAlternateCreateXslt(nodeUuid);
sad.setAlternateCreateXsltName(nodeName);
}
else if (StructuredArtifactDefinitionValidator.PICK_ALTVIEWXSLT_ACTION.equals(sad.getFilePickerAction())) {
sad.setAlternateViewXslt(nodeUuid);
sad.setAlternateViewXsltName(nodeName);
}
else if (StructuredArtifactDefinitionValidator.PICK_TRANSFORM_ACTION.equals(sad.getFilePickerAction())) {
sad.setXslConversionFileId(nodeId);
sad.setXslFileName(nodeName);
}
}
session.removeAttribute(FilePickerHelper.FILE_PICKER_ATTACHMENTS);
session.removeAttribute(FilePickerHelper.FILE_PICKER_CANCEL);
if (sad.getSchemaFile() != null) {
try {
base.put("elements", getStructuredArtifactDefinitionManager().getRootElements(sad));
}
catch (Exception e) {
String errorMessage = "error reading schema file: " + e.getMessage();
sad.setSchemaFile(null);
sad.setSchemaFileName(null);
errors.rejectValue("schemaFile", errorMessage, errorMessage);
}
}
boolean canEdit = getAuthzManager().isAuthorized(SharedFunctionConstants.EDIT_ARTIFACT_DEF,
getIdManager().getId(ToolManager.getCurrentPlacement().getId()));
if (sad.getAlternateCreateXslt() != null){
ContentResource resource = getContentResource(sad.getAlternateCreateXslt(), canEdit);
if ( resource != null ) {
String name = resource.getProperties().getProperty(
resource.getProperties().getNamePropDisplayName());
sad.setAlternateCreateXsltName(name);
}
else {
logger.warn( this+".referenceData: invalid alternateCreateXslt "+sad.getAlternateCreateXslt() );
sad.setAlternateCreateXslt(null);
}
}
if (sad.getAlternateViewXslt() != null){
ContentResource resource = getContentResource(sad.getAlternateViewXslt(), canEdit);
if ( resource != null ) {
String name = resource.getProperties().getProperty(
resource.getProperties().getNamePropDisplayName());
sad.setAlternateViewXsltName(name);
}
else {
logger.warn( this+".referenceData: invalid alternateViewXslt "+sad.getAlternateViewXslt() );
sad.setAlternateViewXslt(null);
}
}
return base;
}
protected ContentResource getContentResource(Id fileId, Boolean canEdit) {
String id = getContentHosting().resolveUuid(fileId.getValue());
if ( id == null )
return null;
ContentResource resource = null;
try {
if (canEdit != null && canEdit) {
String ref = getContentHosting().getReference(id);
SecurityService.pushAdvisor(new LocalSecurityAdvisor(getAuthManager().getAgent().getId().getValue(), "content.read", ref));
}
resource = getContentHosting().getResource(id);
if (canEdit != null && canEdit) {
SecurityService.popAdvisor();
}
} catch (PermissionException e) {
logger.error("", e);
throw new RuntimeException(e);
} catch (IdUnusedException e) {
logger.error("", e);
throw new RuntimeException(e);
} catch (TypeException e) {
logger.error("", e);
throw new RuntimeException(e);
}
return resource;
}
public SessionManager getSessionManager() {
return sessionManager;
}
public void setSessionManager(SessionManager sessionManager) {
this.sessionManager = sessionManager;
}
public ContentHostingService getContentHosting() {
return contentHosting;
}
public void setContentHosting(ContentHostingService contentHosting) {
this.contentHosting = contentHosting;
}
public TransformerFactory getTransformerFactory() {
if (transformerFactory == null) {
transformerFactory = TransformerFactory.newInstance();
}
return transformerFactory;
}
public void setTransformerFactory(TransformerFactory transformerFactory) {
this.transformerFactory = transformerFactory;
}
public URIResolver getUriResolver() {
return uriResolver;
}
public void setUriResolver(URIResolver uriResolver) {
this.uriResolver = uriResolver;
getTransformerFactory().setURIResolver(uriResolver);
}
public class LocalSecurityAdvisor implements SecurityAdvisor {
private String user;
private String function;
private String reference;
public LocalSecurityAdvisor(String user, String function, String reference) {
this.user = user;
this.function = function;
this.reference = reference;
}
public SecurityAdvice isAllowed(String userId, String function, String reference) {
if (userId.equals(this.user) && function.equals(this.function) && reference.equals(this.reference)) {
return SecurityAdvice.ALLOWED;
}
return SecurityAdvice.PASS;
}
}
}