001: /*******************************************************************************
002: * $URL: https://source.sakaiproject.org/svn/metaobj/tags/sakai_2-4-1/metaobj-util/tool-lib/src/java/org/sakaiproject/metaobj/shared/control/XsltArtifactView.java $
003: * $Id: XsltArtifactView.java 21196 2007-02-09 18:57:43Z john.ellis@rsmart.com $
004: * **********************************************************************************
005: *
006: * Copyright (c) 2004, 2005, 2006 The Sakai Foundation.
007: *
008: * Licensed under the Educational Community License, Version 1.0 (the "License");
009: * you may not use this file except in compliance with the License.
010: * You may obtain a copy of the License at
011: *
012: * http://www.opensource.org/licenses/ecl1.php
013: *
014: * Unless required by applicable law or agreed to in writing, software
015: * distributed under the License is distributed on an "AS IS" BASIS,
016: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: * See the License for the specific language governing permissions and
018: * limitations under the License.
019: *
020: ******************************************************************************/package org.sakaiproject.metaobj.shared.control;
021:
022: import org.springframework.web.servlet.view.xslt.AbstractXsltView;
023: import org.springframework.web.context.WebApplicationContext;
024: import org.springframework.web.util.NestedServletException;
025: import org.springframework.validation.Errors;
026: import org.springframework.validation.ObjectError;
027: import org.springframework.validation.FieldError;
028: import org.jdom.transform.JDOMSource;
029: import org.jdom.Element;
030: import org.jdom.Document;
031: import org.sakaiproject.content.api.ResourceEditingHelper;
032: import org.sakaiproject.content.api.ResourceToolAction;
033: import org.sakaiproject.metaobj.shared.mgt.StructuredArtifactDefinitionManager;
034: import org.sakaiproject.metaobj.shared.model.Artifact;
035: import org.sakaiproject.metaobj.shared.model.ElementBean;
036: import org.sakaiproject.metaobj.shared.FormHelper;
037: import org.sakaiproject.component.cover.ComponentManager;
038: import org.sakaiproject.tool.api.ToolSession;
039: import org.sakaiproject.tool.cover.SessionManager;
040: import org.sakaiproject.tool.cover.ToolManager;
041: import org.sakaiproject.util.ResourceLoader;
042: import org.sakaiproject.util.Web;
043:
044: import javax.xml.transform.*;
045: import javax.xml.transform.stream.StreamSource;
046: import javax.xml.transform.stream.StreamResult;
047: import javax.servlet.http.HttpServletRequest;
048: import javax.servlet.http.HttpServletResponse;
049: import java.util.*;
050: import java.io.InputStream;
051:
052: /**
053: * Created by IntelliJ IDEA.
054: * User: johnellis
055: * Date: Oct 30, 2006
056: * Time: 10:10:42 AM
057: * To change this template use File | Settings | File Templates.
058: */
059: public class XsltArtifactView extends AbstractXsltView {
060:
061: private ResourceLoader resourceLoader = new ResourceLoader();
062: private String bundleLocation;
063: private static final String STYLESHEET_PARAMS = "org.sakaiproject.metaobj.shared.control.XsltArtifactView.paramsMap";
064: private static final String STYLESHEET_LOCATION = "org.sakaiproject.metaobj.shared.control.XsltArtifactView.stylesheetLocation";
065: private String uriResolverBeanName;
066: private URIResolver uriResolver;
067: private TransformerFactory transformerFactory = TransformerFactory
068: .newInstance();
069: private boolean readOnly;
070:
071: protected Source createXsltSource(Map map, String string,
072: HttpServletRequest httpServletRequest,
073: HttpServletResponse httpServletResponse) throws Exception {
074:
075: httpServletResponse.setContentType(getContentType());
076: WebApplicationContext context = getWebApplicationContext();
077: setUriResolver((URIResolver) context
078: .getBean(uriResolverBeanName));
079:
080: ToolSession toolSession = SessionManager
081: .getCurrentToolSession();
082:
083: String homeType;
084:
085: ElementBean bean = (ElementBean) map.get("bean");
086:
087: Element root;
088: Map paramsMap = new Hashtable();
089: httpServletRequest.setAttribute(STYLESHEET_PARAMS, paramsMap);
090: if (toolSession.getAttribute(FormHelper.PREVIEW_HOME_TAG) != null) {
091: paramsMap.put("preview", "true");
092: }
093:
094: if (toolSession.getAttribute(ResourceToolAction.ACTION_PIPE) != null) {
095: paramsMap.put("fromResources", "true");
096: }
097:
098: boolean edit = false;
099:
100: if (bean instanceof Artifact) {
101: root = getStructuredArtifactDefinitionManager()
102: .createFormViewXml((Artifact) bean, null);
103: homeType = getHomeType((Artifact) bean);
104: edit = ((Artifact) bean).getId() != null;
105: } else {
106: EditedArtifactStorage sessionBean = (EditedArtifactStorage) httpServletRequest
107: .getSession()
108: .getAttribute(
109: EditedArtifactStorage.EDITED_ARTIFACT_STORAGE_SESSION_KEY);
110:
111: root = getStructuredArtifactDefinitionManager()
112: .createFormViewXml(
113: (Artifact) sessionBean.getRootArtifact(),
114: null);
115:
116: replaceNodes(root, bean, sessionBean);
117: paramsMap.put("subForm", "true");
118: homeType = getHomeType(sessionBean.getRootArtifact());
119: edit = sessionBean.getRootArtifact().getId() != null;
120: }
121:
122: if (edit) {
123: paramsMap.put("edit", "true");
124: }
125:
126: httpServletRequest.setAttribute(STYLESHEET_LOCATION,
127: getStructuredArtifactDefinitionManager()
128: .getTransformer(homeType, readOnly));
129:
130: Errors errors = (Errors) map
131: .get("org.springframework.validation.BindException.bean");
132: if (errors != null && errors.hasErrors()) {
133: Element errorsElement = new Element("errors");
134:
135: List errorsList = errors.getAllErrors();
136:
137: for (Iterator i = errorsList.iterator(); i.hasNext();) {
138: Element errorElement = new Element("error");
139: ObjectError error = (ObjectError) i.next();
140: if (error instanceof FieldError) {
141: FieldError fieldError = (FieldError) error;
142: errorElement.setAttribute("field", fieldError
143: .getField());
144: Element rejectedValue = new Element("rejectedValue");
145: rejectedValue.addContent(fieldError
146: .getRejectedValue().toString());
147: errorElement.addContent(rejectedValue);
148: }
149: Element message = new Element("message");
150: message.addContent(context.getMessage(error,
151: getResourceLoader().getLocale()));
152: errorElement.addContent(message);
153: errorsElement.addContent(errorElement);
154: }
155:
156: root.addContent(errorsElement);
157: }
158:
159: if (httpServletRequest.getParameter("success") != null) {
160: Element success = new Element("success");
161: success.setAttribute("messageKey", httpServletRequest
162: .getParameter("success"));
163: root.addContent(success);
164: }
165:
166: if (toolSession.getAttribute(ResourceEditingHelper.CUSTOM_CSS) != null) {
167: Element uri = new Element("uri");
168: uri.setText((String) toolSession
169: .getAttribute(ResourceEditingHelper.CUSTOM_CSS));
170: root.getChild("css").addContent(uri);
171: }
172:
173: Document doc = new Document(root);
174: return new JDOMSource(doc);
175: }
176:
177: protected String getHomeType(Artifact bean) {
178: if (bean.getHome().getType() == null) {
179: return "new bean";
180: } else if (bean.getHome().getType().getId() == null) {
181: return "new bean";
182: }
183: return bean.getHome().getType().getId().getValue();
184: }
185:
186: protected void replaceNodes(Element root, ElementBean bean,
187: EditedArtifactStorage sessionBean) {
188: Element structuredData = root.getChild("formData").getChild(
189: "artifact").getChild("structuredData");
190: structuredData.removeContent();
191: structuredData.addContent((Element) bean.getBaseElement()
192: .clone());
193:
194: Element schema = root.getChild("formData").getChild("artifact")
195: .getChild("schema");
196: Element schemaRoot = schema.getChild("element");
197: StringTokenizer st = new StringTokenizer(sessionBean
198: .getCurrentPath(), "/");
199: Element newRoot = schemaRoot;
200:
201: while (st.hasMoreTokens()) {
202: String schemaName = st.nextToken();
203: List children = newRoot.getChild("children").getChildren(
204: "element");
205: for (Iterator i = children.iterator(); i.hasNext();) {
206: Element schemaElement = (Element) i.next();
207: if (schemaName.equals(schemaElement
208: .getAttributeValue("name"))) {
209: newRoot = schemaElement;
210: break;
211: }
212: }
213: }
214:
215: schema.removeChild("element");
216: schema.addContent(newRoot.detach());
217: }
218:
219: protected Map getParameters(HttpServletRequest request) {
220: Map params = super .getParameters(request);
221:
222: if (params == null) {
223: params = new Hashtable();
224: }
225:
226: if (ToolManager.getCurrentPlacement() != null) {
227: params.put("panelId", Web.escapeJavascript("Main"
228: + ToolManager.getCurrentPlacement().getId()));
229: }
230:
231: params.putAll((Map) request.getAttribute(STYLESHEET_PARAMS));
232:
233: params.put(STYLESHEET_LOCATION, request
234: .getAttribute(STYLESHEET_LOCATION));
235: return params;
236: }
237:
238: /**
239: * Perform the actual transformation, writing to the given result.
240: * @param source the Source to transform
241: * @param parameters a Map of parameters to be applied to the stylesheet
242: * @param result the result to write to
243: * @throws Exception we let this method throw any exception; the
244: * AbstractXlstView superclass will catch exceptions
245: */
246: protected void doTransform(Source source, Map parameters,
247: Result result, String encoding) throws Exception {
248:
249: InputStream stylesheetLocation = (InputStream) parameters
250: .get(STYLESHEET_LOCATION);
251: try {
252:
253: Transformer trans = getTransformer(stylesheetLocation);
254:
255: // Explicitly apply URIResolver to every created Transformer.
256: if (getUriResolver() != null) {
257: trans.setURIResolver(getUriResolver());
258: }
259:
260: // Apply any subclass supplied parameters to the transformer.
261: if (parameters != null) {
262: for (Iterator it = parameters.entrySet().iterator(); it
263: .hasNext();) {
264: Map.Entry entry = (Map.Entry) it.next();
265: trans.setParameter(entry.getKey().toString(), entry
266: .getValue());
267: }
268: if (logger.isDebugEnabled()) {
269: logger.debug("Added parameters [" + parameters
270: + "] to transformer object");
271: }
272: }
273:
274: // Specify default output properties.
275: trans.setOutputProperty(OutputKeys.ENCODING, encoding);
276: trans.setOutputProperty(OutputKeys.INDENT, "yes");
277:
278: // Xalan-specific, but won't do any harm in other XSLT engines.
279: trans.setOutputProperty(
280: "{http://xml.apache.org/xslt}indent-amount", "2");
281:
282: // Perform the actual XSLT transformation.
283: trans.transform(source, result);
284: if (logger.isDebugEnabled()) {
285: logger.debug("XSLT transformed with stylesheet ["
286: + stylesheetLocation + "]");
287: }
288: } catch (TransformerConfigurationException ex) {
289: throw new NestedServletException(
290: "Couldn't create XSLT transformer for stylesheet ["
291: + stylesheetLocation
292: + "] in XSLT view with name ["
293: + getBeanName() + "]", ex);
294: } catch (TransformerException ex) {
295: throw new NestedServletException(
296: "Couldn't perform transform with stylesheet ["
297: + stylesheetLocation
298: + "] in XSLT view with name ["
299: + getBeanName() + "]", ex);
300: }
301: }
302:
303: protected Transformer getTransformer(InputStream transformer)
304: throws TransformerException {
305: return getTransformerFactory().newTransformer(
306: new StreamSource(transformer));
307: }
308:
309: protected StructuredArtifactDefinitionManager getStructuredArtifactDefinitionManager() {
310: return (StructuredArtifactDefinitionManager) ComponentManager
311: .get("structuredArtifactDefinitionManager");
312: }
313:
314: public String getBundleLocation() {
315: return bundleLocation;
316: }
317:
318: public void setBundleLocation(String bundleLocation) {
319: this .bundleLocation = bundleLocation;
320: setResourceLoader(new ResourceLoader(bundleLocation));
321: }
322:
323: public ResourceLoader getResourceLoader() {
324: return resourceLoader;
325: }
326:
327: public void setResourceLoader(ResourceLoader resourceLoader) {
328: this .resourceLoader = resourceLoader;
329: }
330:
331: public String getUriResolverBeanName() {
332: return uriResolverBeanName;
333: }
334:
335: public void setUriResolverBeanName(String uriResolverBeanName) {
336: this .uriResolverBeanName = uriResolverBeanName;
337: }
338:
339: public URIResolver getUriResolver() {
340: return uriResolver;
341: }
342:
343: public void setUriResolver(URIResolver uriResolver) {
344: this .uriResolver = uriResolver;
345: getTransformerFactory().setURIResolver(uriResolver);
346: }
347:
348: public TransformerFactory getTransformerFactory() {
349: return transformerFactory;
350: }
351:
352: public void setTransformerFactory(
353: TransformerFactory transformerFactory) {
354: this .transformerFactory = transformerFactory;
355: }
356:
357: public boolean isReadOnly() {
358: return readOnly;
359: }
360:
361: public void setReadOnly(boolean readOnly) {
362: this .readOnly = readOnly;
363: }
364:
365: protected void dumpDocument(Element node) {
366: try {
367: Transformer transformer = TransformerFactory.newInstance()
368: .newTransformer();
369: transformer.setOutputProperty(OutputKeys.INDENT, "yes");
370: transformer.transform(new JDOMSource(node),
371: new StreamResult(System.out));
372: } catch (Exception e) {
373: e.printStackTrace();
374: }
375: }
376:
377: }
|