diff --git a/config/alfresco/web-client-application-context.xml b/config/alfresco/web-client-application-context.xml index 4a95f9cbea..4b8537348f 100644 --- a/config/alfresco/web-client-application-context.xml +++ b/config/alfresco/web-client-application-context.xml @@ -30,5 +30,12 @@ + + + + + + + diff --git a/config/alfresco/web-client-config-wizards.xml b/config/alfresco/web-client-config-wizards.xml index 8809ed8785..6e94a43353 100644 --- a/config/alfresco/web-client-config-wizards.xml +++ b/config/alfresco/web-client-config-wizards.xml @@ -173,12 +173,14 @@ description-id="create_xml_content_type_step1_desc" instruction-id="default_instruction" /> + diff --git a/source/java/org/alfresco/web/bean/CheckinCheckoutBean.java b/source/java/org/alfresco/web/bean/CheckinCheckoutBean.java index c517224af3..1964fb629f 100644 --- a/source/java/org/alfresco/web/bean/CheckinCheckoutBean.java +++ b/source/java/org/alfresco/web/bean/CheckinCheckoutBean.java @@ -566,16 +566,16 @@ public class CheckinCheckoutBean { // make content available to the editing screen String contentString = reader.getContentString(); - setDocumentContent(contentString); - setEditorOutput(contentString); - - // navigate to appropriate screen - FacesContext fc = FacesContext.getCurrentInstance(); - this.navigator.setupDispatchContext(node); - String s = (MimetypeMap.MIMETYPE_XML.equals(mimetype) - ? "editXmlInline" - : "editTextInline"); - fc.getApplication().getNavigationHandler().handleNavigation(fc, null, s); + setDocumentContent(contentString); + setEditorOutput(contentString); + + // navigate to appropriate screen + FacesContext fc = FacesContext.getCurrentInstance(); + this.navigator.setupDispatchContext(node); + String s = (MimetypeMap.MIMETYPE_XML.equals(mimetype) + ? "editXmlInline" + : "editTextInline"); + fc.getApplication().getNavigationHandler().handleNavigation(fc, null, s); } else { diff --git a/source/java/org/alfresco/web/bean/content/CreateContentWizard.java b/source/java/org/alfresco/web/bean/content/CreateContentWizard.java index 9f0f94ccff..5756cbb7a3 100644 --- a/source/java/org/alfresco/web/bean/content/CreateContentWizard.java +++ b/source/java/org/alfresco/web/bean/content/CreateContentWizard.java @@ -60,8 +60,6 @@ public class CreateContentWizard extends BaseContentWizard private static final Log LOGGER = LogFactory.getLog(CreateContentWizard.class); - public static final org.alfresco.service.namespace.QName TT_QNAME = - org.alfresco.service.namespace.QName.createQName(org.alfresco.service.namespace.NamespaceService.CONTENT_MODEL_1_0_URI, "tt"); // ------------------------------------------------------------------------------ // Wizard implementation @@ -75,45 +73,20 @@ public class CreateContentWizard extends BaseContentWizard if (this.templateTypeName != null) { LOGGER.debug("generating template output for " + this.templateTypeName); - this.nodeService.setProperty(this.createdNode, TT_QNAME, this.templateTypeName); + this.nodeService.setProperty(this.createdNode, + TemplatingService.TT_QNAME, + this.templateTypeName); TemplatingService ts = TemplatingService.getInstance(); TemplateType tt = this.getTemplateType(); if (tt.getOutputMethods().size() != 0) { - try { - // get the node ref of the node that will contain the content - NodeRef containerNodeRef = this.getContainerNodeRef(); - final String fileName = this.fileName + "-generated.html"; - FileInfo fileInfo = - this.fileFolderService.create(containerNodeRef, - fileName, - ContentModel.TYPE_CONTENT); - NodeRef fileNodeRef = fileInfo.getNodeRef(); - - if (LOGGER.isDebugEnabled()) - LOGGER.debug("Created file node for file: " + - fileName); - - // get a writer for the content and put the file - ContentWriter writer = contentService.getWriter(fileNodeRef, - ContentModel.PROP_CONTENT, true); - // set the mimetype and encoding - writer.setMimetype("text/html"); - writer.setEncoding("UTF-8"); - TemplateOutputMethod tom = tt.getOutputMethods().get(0); - OutputStreamWriter out = - new OutputStreamWriter(writer.getContentOutputStream()); - tom.generate(ts.parseXML(this.content), tt, out); - out.close(); - this.nodeService.setProperty(fileNodeRef, TT_QNAME, this.templateTypeName); - - LOGGER.debug("generated " + fileName + " using " + tom); - } - catch (Exception e) - { - e.printStackTrace(); - throw e; - } + OutputUtil.generate(ts.parseXML(this.content), + tt, + this.fileName, + this.getContainerNodeRef(), + this.fileFolderService, + this.contentService, + this.nodeService); } } diff --git a/source/java/org/alfresco/web/bean/content/CreateXmlContentTypeWizard.java b/source/java/org/alfresco/web/bean/content/CreateXmlContentTypeWizard.java index 8bed4a9c54..a2d4cd8286 100644 --- a/source/java/org/alfresco/web/bean/content/CreateXmlContentTypeWizard.java +++ b/source/java/org/alfresco/web/bean/content/CreateXmlContentTypeWizard.java @@ -78,14 +78,14 @@ public class CreateXmlContentTypeWizard extends BaseWizardBean this.fileFolderService.create(containerNodeRef, this.getSchemaFileName(), ContentModel.TYPE_CONTENT); - NodeRef fileNodeRef = fileInfo.getNodeRef(); - + final NodeRef schemaFileNodeRef = fileInfo.getNodeRef(); + if (LOGGER.isDebugEnabled()) LOGGER.debug("Created file node for file: " + this.getSchemaFileName()); // get a writer for the content and put the file - ContentWriter writer = contentService.getWriter(fileNodeRef, + ContentWriter writer = contentService.getWriter(schemaFileNodeRef, ContentModel.PROP_CONTENT, true); // set the mimetype and encoding writer.setMimetype("text/xml"); @@ -95,14 +95,14 @@ public class CreateXmlContentTypeWizard extends BaseWizardBean fileInfo = this.fileFolderService.create(containerNodeRef, this.getPresentationTemplateFileName(), ContentModel.TYPE_CONTENT); - fileNodeRef = fileInfo.getNodeRef(); + final NodeRef presentationTemplateFileNodeRef = fileInfo.getNodeRef(); if (LOGGER.isDebugEnabled()) LOGGER.debug("Created file node for file: " + this.getPresentationTemplateFileName()); // get a writer for the content and put the file - writer = contentService.getWriter(fileNodeRef, + writer = contentService.getWriter(presentationTemplateFileNodeRef, ContentModel.PROP_CONTENT, true); // set the mimetype and encoding writer.setMimetype("text/xml"); @@ -110,7 +110,14 @@ public class CreateXmlContentTypeWizard extends BaseWizardBean writer.putContent(this.getPresentationTemplateFile()); final TemplatingService ts = TemplatingService.getInstance(); - ts.registerTemplateType(this.getTemplateType()); + final String rootTagName = + this.getSchemaFileName().replaceAll("([^\\.])\\..+", "$1"); + final TemplateType tt = ts.newTemplateType(rootTagName, schemaFileNodeRef); + if (this.getPresentationTemplateFile() != null) + { + tt.addOutputMethod(new XSLTOutputMethod(presentationTemplateFileNodeRef)); + } + ts.registerTemplateType(tt); // return the default outcome return outcome; @@ -278,25 +285,6 @@ public class CreateXmlContentTypeWizard extends BaseWizardBean { return this.getFile("pt"); } - - public TemplateType getTemplateType() - throws ParserConfigurationException, - SAXException, - IOException - { - if (this.getSchemaFile() == null) - return null; - final TemplatingService ts = TemplatingService.getInstance(); - final String rootTagName = - this.getSchemaFileName().replaceAll("([^\\.])\\..+", "$1"); - final Document d = ts.parseXML(this.getSchemaFile()); - final TemplateType result = ts.newTemplateType(rootTagName, d); - if (this.getPresentationTemplateFile() != null) - { - result.addOutputMethod(new XSLTOutputMethod(this.getPresentationTemplateFile())); - } - return result; - } /** * @return Returns a list of mime types to allow the user to select from diff --git a/source/java/org/alfresco/web/templating/OutputUtil.java b/source/java/org/alfresco/web/templating/OutputUtil.java new file mode 100644 index 0000000000..ccdd5e0aab --- /dev/null +++ b/source/java/org/alfresco/web/templating/OutputUtil.java @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2005 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * 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.alfresco.web.templating; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.ResourceBundle; + +import javax.faces.context.FacesContext; +import javax.faces.event.ValueChangeEvent; +import javax.faces.model.SelectItem; + +import org.alfresco.config.Config; +import org.alfresco.config.ConfigElement; +import org.alfresco.config.ConfigService; +import org.alfresco.repo.content.MimetypeMap; +import org.alfresco.web.app.AlfrescoNavigationHandler; +import org.alfresco.web.app.Application; +import org.alfresco.web.bean.repository.Node; +import org.alfresco.web.data.IDataContainer; +import org.alfresco.web.data.QuickSort; +import org.alfresco.web.templating.*; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.alfresco.model.ContentModel; +import org.alfresco.service.cmr.model.FileInfo; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.ContentWriter; +import java.io.OutputStreamWriter; +import org.alfresco.web.app.servlet.FacesHelper; +import org.alfresco.service.cmr.model.FileFolderService; +import org.alfresco.service.cmr.repository.ContentService; +import org.alfresco.service.cmr.repository.NodeService; +import org.w3c.dom.Document; +import org.alfresco.repo.avm.*; + +public class OutputUtil +{ + private static final Log LOGGER = LogFactory.getLog(OutputUtil.class); + + public static void generate(Document xml, + TemplateType tt, + String fileName, + NodeRef containerNodeRef, + FileFolderService fileFolderService, + ContentService contentService, + NodeService nodeService) + throws Exception + { + try { + // get the node ref of the node that will contain the content + fileName = fileName + "-generated.html"; + FileInfo fileInfo = + fileFolderService.create(containerNodeRef, + fileName, + ContentModel.TYPE_CONTENT); + NodeRef fileNodeRef = fileInfo.getNodeRef(); + + if (LOGGER.isDebugEnabled()) + LOGGER.debug("Created file node for file: " + + fileName); + + // get a writer for the content and put the file + ContentWriter writer = contentService.getWriter(fileNodeRef, + ContentModel.PROP_CONTENT, true); + // set the mimetype and encoding + writer.setMimetype("text/html"); + writer.setEncoding("UTF-8"); + TemplateOutputMethod tom = tt.getOutputMethods().get(0); + OutputStreamWriter out = + new OutputStreamWriter(writer.getContentOutputStream()); + tom.generate(xml, tt, out); + out.close(); + nodeService.setProperty(fileNodeRef, + TemplatingService.TT_QNAME, + tt.getName()); + + LOGGER.debug("generated " + fileName + " using " + tom); + + AVMService avmService = AVMContext.fgInstance.getAVMService(); + String parentPath = "repo-1:/repo-1/alice/appBase/avm_webapps/my_webapp"; + try + { + out = new OutputStreamWriter(avmService.createFile(parentPath, fileName)); + } + catch (AVMExistsException e) + { + out = new OutputStreamWriter(avmService.getFileOutputStream(parentPath + "/" + fileName)); + } + LOGGER.debug("generating " + fileName + " to avm"); + tom.generate(xml, tt, out); + out.close(); + } + catch (Exception e) + { + LOGGER.error(e); + e.printStackTrace(); + throw e; + } + } +} \ No newline at end of file diff --git a/source/java/org/alfresco/web/templating/TemplateInputMethod.java b/source/java/org/alfresco/web/templating/TemplateInputMethod.java index ec7a8d144d..77ab79a5f8 100644 --- a/source/java/org/alfresco/web/templating/TemplateInputMethod.java +++ b/source/java/org/alfresco/web/templating/TemplateInputMethod.java @@ -17,9 +17,11 @@ package org.alfresco.web.templating; import org.w3c.dom.Document; +import java.io.Serializable; import java.io.Writer; public interface TemplateInputMethod + extends Serializable { public void generate(final InstanceData instanceData, final TemplateType tt, diff --git a/source/java/org/alfresco/web/templating/TemplateOutputMethod.java b/source/java/org/alfresco/web/templating/TemplateOutputMethod.java index b7827dc836..e2c8d73550 100644 --- a/source/java/org/alfresco/web/templating/TemplateOutputMethod.java +++ b/source/java/org/alfresco/web/templating/TemplateOutputMethod.java @@ -16,11 +16,12 @@ */ package org.alfresco.web.templating; +import java.io.Serializable; import java.io.Writer; - import org.w3c.dom.Document; public interface TemplateOutputMethod + extends Serializable { public void generate(final Document xmlContent, diff --git a/source/java/org/alfresco/web/templating/TemplateType.java b/source/java/org/alfresco/web/templating/TemplateType.java index c03c8f5e94..3bc74ea079 100644 --- a/source/java/org/alfresco/web/templating/TemplateType.java +++ b/source/java/org/alfresco/web/templating/TemplateType.java @@ -18,14 +18,21 @@ package org.alfresco.web.templating; import org.w3c.dom.Document; import java.util.List; +import java.io.Serializable; +//import org.alfresco.service.cmr.repository.NodeRef; public interface TemplateType + extends Serializable { public String getName(); public Document getSchema(); +// public void setSchemaNodeRef(final NodeRef nodeRef); +// +// public NodeRef getSchemaNodeRef(); + public Document getSampleXml(final String rootTagName); public List getInputMethods(); diff --git a/source/java/org/alfresco/web/templating/TemplatingService.java b/source/java/org/alfresco/web/templating/TemplatingService.java index 59ee466128..3d5030b409 100644 --- a/source/java/org/alfresco/web/templating/TemplatingService.java +++ b/source/java/org/alfresco/web/templating/TemplatingService.java @@ -34,16 +34,86 @@ import org.xml.sax.SAXException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -public class TemplatingService +import org.alfresco.service.cmr.repository.ContentReader; +import org.alfresco.service.cmr.repository.ContentService; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.model.ContentModel; +import org.alfresco.util.TempFileProvider; + +public final class TemplatingService + implements Serializable { + + //////////////////////////////////////////////////////////////////////////// + + private static class Configuration + { + private final static File CONFIG_FILE = + new File(TempFileProvider.getTempDir(), "templating_configuration.xml"); + + public static void load() + throws IOException + { + if (!CONFIG_FILE.exists()) + return; + final TemplatingService ts = TemplatingService.getInstance(); + final ObjectInputStream out = new ObjectInputStream(new FileInputStream(CONFIG_FILE)); + try + { + final List tt = (List)out.readObject(); + for (TemplateType t : tt) + { + ts.registerTemplateType(t); + } + out.close(); + } + catch (ClassNotFoundException cnfe) + { + assert false : cnfe; + TemplatingService.LOGGER.error(cnfe); + } + } + + public static void save() + throws IOException + { + if (!CONFIG_FILE.exists()) + CONFIG_FILE.createNewFile(); + final TemplatingService ts = TemplatingService.getInstance(); + final ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(CONFIG_FILE)); + out.writeObject(ts.getTemplateTypes()); + out.close(); + } + } + + //////////////////////////////////////////////////////////////////////////// + + + public static final org.alfresco.service.namespace.QName TT_QNAME = + org.alfresco.service.namespace.QName.createQName(org.alfresco.service.namespace.NamespaceService.CONTENT_MODEL_1_0_URI, "tt"); + private static final Log LOGGER = LogFactory.getLog(TemplatingService.class); - private final static TemplatingService INSTANCE = new TemplatingService(); + private static TemplatingService INSTANCE; private ArrayList templateTypes = new ArrayList(); + private final ContentService contentService; - private TemplatingService() + public TemplatingService(final ContentService contentService) { + this.contentService = contentService; + if (INSTANCE == null) + { + INSTANCE = this; + try + { + Configuration.load(); + } + catch (IOException ioe) + { + LOGGER.error(ioe); + } + } } public static TemplatingService getInstance() @@ -71,12 +141,20 @@ public class TemplatingService public void registerTemplateType(final TemplateType tt) { this.templateTypes.add(tt); + try + { + Configuration.save(); + } + catch (IOException ioe) + { + LOGGER.error(ioe); + } } public TemplateType newTemplateType(final String name, - final Document schema) + final NodeRef schemaNodeRef) { - return new TemplateTypeImpl(name, schema); + return new TemplateTypeImpl(name, schemaNodeRef); } public Document newDocument() @@ -125,7 +203,6 @@ public class TemplatingService public void writeXML(final Node n, final File output) throws IOException { - this.writeXML(n, new FileWriter(output)); } @@ -144,6 +221,17 @@ public class TemplatingService return this.parseXML(new ByteArrayInputStream(source.getBytes())); } + public Document parseXML(final NodeRef nodeRef) + throws ParserConfigurationException, + SAXException, + IOException + { + final ContentReader contentReader = + this.contentService.getReader(nodeRef, ContentModel.TYPE_CONTENT); + final InputStream in = contentReader.getContentInputStream(); + return this.parseXML(in); + } + public Document parseXML(final File source) throws ParserConfigurationException, SAXException, diff --git a/source/java/org/alfresco/web/templating/xforms/TemplateTypeImpl.java b/source/java/org/alfresco/web/templating/xforms/TemplateTypeImpl.java index 3661ddedaf..3603a67753 100644 --- a/source/java/org/alfresco/web/templating/xforms/TemplateTypeImpl.java +++ b/source/java/org/alfresco/web/templating/xforms/TemplateTypeImpl.java @@ -19,6 +19,7 @@ package org.alfresco.web.templating.xforms; import java.io.*; import java.util.*; import javax.xml.parsers.ParserConfigurationException; +import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.util.TempFileProvider; import org.alfresco.web.templating.*; @@ -27,23 +28,35 @@ import org.alfresco.web.templating.xforms.schemabuilder.FormBuilderException; import org.apache.xmlbeans.*; import org.apache.xmlbeans.impl.xsd2inst.SampleXmlUtil; -import org.w3c.dom.Document; -import org.w3c.dom.Node; +import org.w3c.dom.*; import org.xml.sax.SAXException; +import org.alfresco.model.ContentModel; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; public class TemplateTypeImpl implements TemplateType { + private static final Log LOGGER = LogFactory.getLog(TemplateTypeImpl.class); - private final Document schema; + private transient Document schema; + private final NodeRef schemaNodeRef; private final String name; - private final LinkedList outputMethods = new LinkedList(); + private final LinkedList outputMethods = + new LinkedList(); + private final static LinkedList INPUT_METHODS = + new LinkedList(); + static + { + INPUT_METHODS.add(new XFormsInputMethod()); + } + public TemplateTypeImpl(final String name, - final Document schema) + final NodeRef schemaNodeRef) { this.name = name; - this.schema = schema; + this.schemaNodeRef = schemaNodeRef; } public String getName() @@ -53,6 +66,18 @@ public class TemplateTypeImpl public Document getSchema() { + if (this.schema == null) + { + final TemplatingService ts = TemplatingService.getInstance(); + try + { + this.schema = ts.parseXML(this.schemaNodeRef); + } + catch (Exception e) + { + LOGGER.error(e); + } + } return this.schema; } @@ -63,15 +88,11 @@ public class TemplateTypeImpl final XmlObject[] schemas = new XmlObject[1]; try { - final File schemaFile = TempFileProvider.createTempFile("alfresco", ".schema"); - TemplatingService.getInstance().writeXML(this.schema, schemaFile); - schemas[0] = XmlObject.Factory.parse(schemaFile, xmlOptions); - schemaFile.delete(); + schemas[0] = XmlObject.Factory.parse(this.getSchema(), xmlOptions); } - catch (Exception e) + catch (XmlException xmle) { - System.err.println("Can not load schema file: " + schema + ": "); - e.printStackTrace(); + LOGGER.error(xmle); } final XmlOptions compileOptions = new XmlOptions(); @@ -88,8 +109,7 @@ public class TemplateTypeImpl } catch (XmlException xmle) { - xmle.printStackTrace(); - return null; + LOGGER.error(xmle); } if (sts == null) @@ -110,11 +130,18 @@ public class TemplateTypeImpl if (elem == null) throw new NullPointerException("Could not find a global element with name \"" + rootTagName + "\""); - final String result = SampleXmlUtil.createSampleForType(elem); + final String xmlString = SampleXmlUtil.createSampleForType(elem); try { final TemplatingService ts = TemplatingService.getInstance(); - return ts.parseXML(new ByteArrayInputStream(result.getBytes())); + final Document d = ts.parseXML(new ByteArrayInputStream(xmlString.getBytes())); + System.out.println("sample xml:"); + System.out.println(ts.writeXMLToString(d)); + + TemplateTypeImpl.cleanUpSampleXml(d.getDocumentElement()); + System.out.println("cleaned up xml:"); + System.out.println(ts.writeXMLToString(d)); + return d; } catch (ParserConfigurationException pce) { @@ -133,11 +160,32 @@ public class TemplateTypeImpl } } + private static void cleanUpSampleXml(final Node n) + { + if (n instanceof CharacterData) + { + // System.out.println("replacing data " + ((CharacterData)n).getData()); + ((CharacterData)n).setData(" "); + } + else if (n instanceof Element) + { + final NamedNodeMap attrs = n.getAttributes(); + for (int i = 0; i < attrs.getLength(); i++) + { + // System.out.println("not replacing data " + ((Attr)n).getValue()); + // ((Attr)attrs.item(i)).setValue(""); + } + } + final NodeList nl = n.getChildNodes(); + for (int i = 0; i < nl.getLength(); i++) + { + TemplateTypeImpl.cleanUpSampleXml(nl.item(i)); + } + } + public List getInputMethods() { - return (List)Arrays.asList(new TemplateInputMethod[] { - new XFormsInputMethod() - }); + return INPUT_METHODS; } public void addOutputMethod(TemplateOutputMethod output) diff --git a/source/java/org/alfresco/web/templating/xforms/XFormsInputMethod.java b/source/java/org/alfresco/web/templating/xforms/XFormsInputMethod.java index 100599771d..41ca4f0916 100644 --- a/source/java/org/alfresco/web/templating/xforms/XFormsInputMethod.java +++ b/source/java/org/alfresco/web/templating/xforms/XFormsInputMethod.java @@ -21,7 +21,6 @@ import javax.faces.context.FacesContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.ServletContext; -import org.alfresco.util.TempFileProvider; import org.alfresco.web.templating.*; import org.alfresco.web.templating.xforms.schemabuilder.*; import org.alfresco.web.bean.ajax.XFormsBean; @@ -105,16 +104,6 @@ public class XFormsInputMethod if (xmlContent == null) xmlContent = tt.getSampleXml(tt.getName()); final TemplatingService ts = TemplatingService.getInstance(); - final File schemaFile = TempFileProvider.createTempFile("alfresco", ".schema"); - try - { - ts.writeXML(tt.getSchema(), schemaFile); - } - catch (IOException ioe) - { - assert false : ioe.getMessage(); - LOGGER.error(ioe); - } final FacesContext fc = FacesContext.getCurrentInstance(); final HttpServletRequest request = (HttpServletRequest) fc.getExternalContext().getRequest(); @@ -124,16 +113,16 @@ public class XFormsInputMethod LOGGER.debug("using baseUrl " + baseUrl + " for schemaformbuilder"); final SchemaFormBuilder builder = - new BaseSchemaFormBuilder(getDocumentElementNameNoNS(xmlContent), + new BaseSchemaFormBuilder(tt.getName(), xmlContent, request.getContextPath() + "/ajax/invoke/XFormsBean.handleAction", - "post", + SchemaFormBuilder.SUBMIT_METHOD_POST, new XHTMLWrapperElementsBuilder(), null, baseUrl, true); - LOGGER.debug("building xform for schema " + schemaFile.getPath()); - final Document result = builder.buildForm(schemaFile.getPath()); + LOGGER.debug("building xform for schema " + tt.getName()); + final Document result = builder.buildForm(tt); //schemaFile.getPath()); // xmlContentFile.delete(); // schemaFile.delete(); return result; diff --git a/source/java/org/alfresco/web/templating/xforms/XSLTOutputMethod.java b/source/java/org/alfresco/web/templating/xforms/XSLTOutputMethod.java index d2a4b00b76..2202a5d36f 100644 --- a/source/java/org/alfresco/web/templating/xforms/XSLTOutputMethod.java +++ b/source/java/org/alfresco/web/templating/xforms/XSLTOutputMethod.java @@ -35,16 +35,17 @@ import javax.xml.transform.stream.StreamResult; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.xml.sax.SAXException; +import org.alfresco.service.cmr.repository.NodeRef; public class XSLTOutputMethod implements TemplateOutputMethod { - private final File file; + private final NodeRef nodeRef; - public XSLTOutputMethod(final File f) + public XSLTOutputMethod(final NodeRef nodeRef) { - this.file = f; + this.nodeRef = nodeRef; } public void generate(final Document xmlContent, @@ -58,7 +59,7 @@ public class XSLTOutputMethod { TransformerFactory tf = TransformerFactory.newInstance(); TemplatingService ts = TemplatingService.getInstance(); - DOMSource source = new DOMSource(ts.parseXML(this.file)); + DOMSource source = new DOMSource(ts.parseXML(this.nodeRef)); final Templates templates = tf.newTemplates(source); final Transformer t = templates.newTransformer(); final StreamResult result = new StreamResult(out); diff --git a/source/java/org/alfresco/web/templating/xforms/schemabuilder/AbstractSchemaFormBuilder.java b/source/java/org/alfresco/web/templating/xforms/schemabuilder/AbstractSchemaFormBuilder.java index d26c2b9a8a..6cfb8fdf97 100644 --- a/source/java/org/alfresco/web/templating/xforms/schemabuilder/AbstractSchemaFormBuilder.java +++ b/source/java/org/alfresco/web/templating/xforms/schemabuilder/AbstractSchemaFormBuilder.java @@ -24,7 +24,7 @@ import org.chiba.xml.xforms.NamespaceCtx; import org.w3c.dom.*; import org.w3c.dom.bootstrap.DOMImplementationRegistry; import org.xml.sax.InputSource; - +import org.alfresco.web.templating.*; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; @@ -33,7 +33,7 @@ import java.io.File; import java.io.IOException; import java.io.StringWriter; import java.util.*; - +import org.alfresco.util.TempFileProvider; /* * Search for TODO for things remaining to-do in this implementation. * @@ -199,32 +199,6 @@ public abstract class AbstractSchemaFormBuilder implements SchemaFormBuilder { PROPERTY_PREFIX + "group@border"; private static final String DEFAULT_GROUP_BORDER = "0"; - /** - * Prossible values of the "@method" on the "submission" element - */ - public static final String SUBMIT_METHOD_POST = "post"; - - /** - * __UNDOCUMENTED__ - */ - public static final String SUBMIT_METHOD_PUT = "put"; - - /** - * __UNDOCUMENTED__ - */ - public static final String SUBMIT_METHOD_GET = "get"; - - /** - * __UNDOCUMENTED__ - */ - public static final String SUBMIT_METHOD_FORM_DATA_POST = "form-data-post"; - - /** - * __UNDOCUMENTED__ - */ - public static final String SUBMIT_METHOD_URLENCODED_POST = - "urlencoded-post"; - /** * __UNDOCUMENTED__ */ @@ -418,33 +392,6 @@ public abstract class AbstractSchemaFormBuilder implements SchemaFormBuilder { return _submitMethod; } - private void loadSchema(String inputURI) - throws ClassNotFoundException, - InstantiationException, - IllegalAccessException - { - - // Get DOM Implementation using DOM Registry - System.setProperty(DOMImplementationRegistry.PROPERTY, - "org.apache.xerces.dom.DOMXSImplementationSourceImpl"); - DOMImplementationRegistry registry = - DOMImplementationRegistry.newInstance(); - Object o = registry.getDOMImplementation("XS-Loader"); - if (o instanceof XSImplementation) - { - XSImplementation impl = (XSImplementation) o; - XSLoader schemaLoader = impl.createXSLoader(null); - this.schema = schemaLoader.loadURI(inputURI); - } - else if (o != null) - { - if (LOGGER.isDebugEnabled()) - LOGGER.debug("DOMImplementation is not a XSImplementation: " - + o.getClass().getName()); - throw new RuntimeException(o.getClass().getName() + " is not a XSImplementation"); - } - } - /** * builds a form from a XML schema. * @@ -452,37 +399,62 @@ public abstract class AbstractSchemaFormBuilder implements SchemaFormBuilder { * @return __UNDOCUMENTED__ * @throws FormBuilderException __UNDOCUMENTED__ */ - public Document buildForm(String inputFile) + public Document buildForm(final TemplateType tt) throws FormBuilderException { try { - this.loadSchema(new File(inputFile).toURI().toString()); - this.buildTypeTree(schema); + // Get DOM Implementation using DOM Registry + System.setProperty(DOMImplementationRegistry.PROPERTY, + "org.apache.xerces.dom.DOMXSImplementationSourceImpl"); + final DOMImplementationRegistry registry = + DOMImplementationRegistry.newInstance(); + final XSImplementation xsImpl = (XSImplementation) + registry.getDOMImplementation("XS-Loader"); + // final DOMImplementationLS lsImpl = (DOMImplementationLS) + // registry.getDOMImplementation("XML 1.0 LS 3.0"); + // LSInput in = lsImpl.createLSInput(); + // in.setCharacterStrea + final TemplatingService ts = TemplatingService.getInstance(); + final File schemaFile = TempFileProvider.createTempFile("alfresco", ".schema"); + try + { + ts.writeXML(tt.getSchema(), schemaFile); + } + catch (IOException ioe) + { + assert false : ioe.getMessage(); + LOGGER.error(ioe); + } + + final String inputURI = schemaFile.toURI().toString(); + final XSLoader schemaLoader = xsImpl.createXSLoader(null); + this.schema = schemaLoader.loadURI(inputURI); + this.buildTypeTree(this.schema); //refCounter = 0; - counter = new HashMap(); - - Document xForm = createFormTemplate(_rootTagName, - _rootTagName + " Form", - getProperty(CSS_STYLE_PROP, - DEFAULT_CSS_STYLE_PROP)); + this.counter = new HashMap(); + final Document xForm = createFormTemplate(_rootTagName, + _rootTagName + " Form", + getProperty(CSS_STYLE_PROP, + DEFAULT_CSS_STYLE_PROP)); + //this.buildInheritenceTree(schema); Element envelopeElement = xForm.getDocumentElement(); //Element formSection = (Element) envelopeElement.getElementsByTagNameNS(CHIBA_NS, "form").item(0); //Element formSection =(Element) envelopeElement.getElementsByTagName("body").item(0); //find form element: last element created - NodeList children = xForm.getDocumentElement().getChildNodes(); + final NodeList children = xForm.getDocumentElement().getChildNodes(); - Element formSection = (Element)children.item(children.getLength() - 1); - Element modelSection = (Element) + final Element formSection = (Element)children.item(children.getLength() - 1); + final Element modelSection = (Element) envelopeElement.getElementsByTagNameNS(XFORMS_NS, "model").item(0); //add XMLSchema if we use schema types if (_useSchemaTypes && modelSection != null) modelSection.setAttributeNS(XFORMS_NS, this.getXFormsNSPrefix() + "schema", - new File(inputFile).toURI().toString()); + inputURI); //change stylesheet String stylesheet = this.getStylesheet(); @@ -502,7 +474,7 @@ public abstract class AbstractSchemaFormBuilder implements SchemaFormBuilder { //TODO: find a better way to find the targetNamespace try { - Document domDoc = DOMUtil.parseXmlFile(inputFile, true, false); + final Document domDoc = tt.getSchema(); if (domDoc != null) { Element root = domDoc.getDocumentElement(); @@ -1167,14 +1139,14 @@ public abstract class AbstractSchemaFormBuilder implements SchemaFormBuilder { int[] occurance = this.getOccurance(owner); addSimpleType(xForm, - modelSection, - formSection, - controlType, - owner.getName(), - owner, - pathToRoot, - occurance[0], - occurance[1]); + modelSection, + formSection, + controlType, + owner.getName(), + owner, + pathToRoot, + occurance[0], + occurance[1]); } private void addAttributeSet(Document xForm, @@ -1189,20 +1161,22 @@ public abstract class AbstractSchemaFormBuilder implements SchemaFormBuilder { if (attrUses != null) { int nbAttr = attrUses.getLength(); for (int i = 0; i < nbAttr; i++) { - XSAttributeUse currentAttributeUse = - (XSAttributeUse) attrUses.item(i); + XSAttributeUse currentAttributeUse = (XSAttributeUse)attrUses.item(i); XSAttributeDeclaration currentAttribute = - currentAttributeUse.getAttrDeclaration(); + currentAttributeUse.getAttrDeclaration(); //test if extended ! - if (checkIfExtension && this.doesAttributeComeFromExtension(currentAttributeUse, controlType)) { - if (LOGGER.isDebugEnabled()) { + if (checkIfExtension && + this.doesAttributeComeFromExtension(currentAttributeUse, controlType)) + { + if (LOGGER.isDebugEnabled()) + { LOGGER.debug("This attribute comes from an extension: recopy form controls. \n Model section: "); DOMUtil.prettyPrintDOM(modelSection); } String attributeName = currentAttributeUse.getName(); - if (attributeName == null || attributeName.equals("")) + if (attributeName == null || attributeName.length() == 0) attributeName = currentAttributeUse.getAttrDeclaration().getName(); //find the existing bind Id @@ -1248,7 +1222,7 @@ public abstract class AbstractSchemaFormBuilder implements SchemaFormBuilder { } else { String newPathToRoot; - if ((pathToRoot == null) || pathToRoot.equals("")) { + if (pathToRoot == null || pathToRoot.length() == 0) { newPathToRoot = "@" + currentAttribute.getName(); } else if (pathToRoot.endsWith("/")) { newPathToRoot = @@ -1266,11 +1240,11 @@ public abstract class AbstractSchemaFormBuilder implements SchemaFormBuilder { }*/ addSimpleType(xForm, - modelSection, - formSection, - simpleType, - currentAttributeUse, - newPathToRoot); + modelSection, + formSection, + simpleType, + currentAttributeUse, + newPathToRoot); } } } @@ -1411,12 +1385,12 @@ public abstract class AbstractSchemaFormBuilder implements SchemaFormBuilder { //attributes addAttributeSet(xForm, - modelSection, - formSection, - controlType, - owner, - pathToRoot, - checkIfExtension); + modelSection, + formSection, + controlType, + owner, + pathToRoot, + checkIfExtension); //process group XSParticle particle = controlType.getParticle(); diff --git a/source/java/org/alfresco/web/templating/xforms/schemabuilder/SchemaFormBuilder.java b/source/java/org/alfresco/web/templating/xforms/schemabuilder/SchemaFormBuilder.java index e710766769..c0697e8388 100644 --- a/source/java/org/alfresco/web/templating/xforms/schemabuilder/SchemaFormBuilder.java +++ b/source/java/org/alfresco/web/templating/xforms/schemabuilder/SchemaFormBuilder.java @@ -25,6 +25,8 @@ import org.w3c.dom.Element; import javax.xml.transform.Source; import java.util.Properties; +import org.alfresco.web.templating.*; + /** * An object that implements this interface can build an XForm that conforms to * the elements and attributes declared in an XML Schema. @@ -101,6 +103,32 @@ public interface SchemaFormBuilder { */ public static final String xmleventsNSPrefix = "ev:"; + /** + * Prossible values of the "@method" on the "submission" element + */ + public static final String SUBMIT_METHOD_POST = "post"; + + /** + * __UNDOCUMENTED__ + */ + public static final String SUBMIT_METHOD_PUT = "put"; + + /** + * __UNDOCUMENTED__ + */ + public static final String SUBMIT_METHOD_GET = "get"; + + /** + * __UNDOCUMENTED__ + */ + public static final String SUBMIT_METHOD_FORM_DATA_POST = "form-data-post"; + + /** + * __UNDOCUMENTED__ + */ + public static final String SUBMIT_METHOD_URLENCODED_POST = + "urlencoded-post"; + /** * __UNDOCUMENTED__ * @@ -174,7 +202,8 @@ public interface SchemaFormBuilder { * @throws org.chiba.tools.schemabuilder.FormBuilderException * If an error occurs building the XForm. */ - public Document buildForm(String inputURI) throws FormBuilderException; + public Document buildForm(final TemplateType tt) + throws FormBuilderException; /** * Creates a caption for the provided text extracted from the XML Schema. diff --git a/source/web/jsp/content/create-content-wizard/create-xml.jsp b/source/web/jsp/content/create-content-wizard/create-xml.jsp index 0df82adc2b..0d29443c92 100644 --- a/source/web/jsp/content/create-content-wizard/create-xml.jsp +++ b/source/web/jsp/content/create-content-wizard/create-xml.jsp @@ -35,7 +35,9 @@ final InstanceData instanceData = new InstanceData() { { try { - return wiz.getContent() != null ? ts.parseXML(wiz.getContent()) : null; + return (wiz.getContent() != null + ? ts.parseXML(wiz.getContent()) + : null); } catch (Exception e) { diff --git a/source/web/jsp/content/create-xml-content-type-wizard/configure-presentation-templates.jsp b/source/web/jsp/content/create-xml-content-type-wizard/configure-presentation-templates.jsp index ec5fc05aab..ac9ac327cc 100644 --- a/source/web/jsp/content/create-xml-content-type-wizard/configure-presentation-templates.jsp +++ b/source/web/jsp/content/create-xml-content-type-wizard/configure-presentation-templates.jsp @@ -41,12 +41,14 @@ +<%-- +--%> diff --git a/source/web/scripts/ajax/xforms.js b/source/web/scripts/ajax/xforms.js index 25969cff63..d00c57ae62 100644 --- a/source/web/scripts/ajax/xforms.js +++ b/source/web/scripts/ajax/xforms.js @@ -1,4 +1,5 @@ dojo.require("dojo.widget.DebugConsole"); +dojo.require("dojo.widget.DatePicker"); dojo.require("dojo.widget.Button"); dojo.require("dojo.widget.validate"); dojo.require("dojo.widget.ComboBox"); @@ -136,7 +137,7 @@ function load_body(body, ui_element_stack) nodeRef.setAttribute("style", "height: 200px; border: solid 1px black;"); cell.appendChild(nodeRef); var id = o.getAttribute("id"); - var initial_value = get_initial_value(o); + var initial_value = get_initial_value(o) || ""; nodeRef.appendChild(document.createTextNode(initial_value)); var w = dojo.widget.createWidget("Editor", { @@ -181,10 +182,11 @@ function load_body(body, ui_element_stack) row.appendChild(cell); var nodeRef = document.createElement("div"); cell.appendChild(nodeRef); - var value = get_initial_value(o); + var initial_value = get_initial_value(o); switch (get_type(o)) { case "date": + initial_value = initial_value || dojo.widget.DatePicker.util.toRfcDate(); var dateTextBoxDiv = document.createElement("div"); nodeRef.appendChild(dateTextBoxDiv); var dateTextBox = dojo.widget.createWidget("DateTextBox", @@ -192,7 +194,7 @@ function load_body(body, ui_element_stack) widgetId: id, required: is_required(o), format: "YYYY-MM-DD", - value: value + value: initial_value }, dateTextBoxDiv); dateTextBox.onfocus = function(o) { @@ -205,7 +207,7 @@ function load_body(body, ui_element_stack) dateTextBox.picker = dojo.widget.createWidget("DatePicker", { isHidden: true, - value : value + value : initial_value }, datePickerDiv); dateTextBox.picker.hide(); @@ -223,11 +225,12 @@ function load_body(body, ui_element_stack) case "integer": case "positiveInteger": case "negativeInteger": + initial_value = initial_value || ""; var w = dojo.widget.createWidget("SpinnerIntegerTextBox", { widgetId: id, required: is_required(o), - value: value + value: initial_value }, nodeRef); var handler = function(event) @@ -242,11 +245,12 @@ function load_body(body, ui_element_stack) dojo.event.connect(w, "onkeyup", handler); break; case "double": + initial_value = initial_value || "0"; var w = dojo.widget.createWidget("SpinnerRealNumberTextBox", { widgetId: id, required: is_required(o), - value: value + value: initial_value }, nodeRef); var handler = function(event) @@ -262,11 +266,12 @@ function load_body(body, ui_element_stack) break; case "string": default: + initial_value = initial_value || ""; var w = dojo.widget.createWidget("ValidationTextBox", { widgetId: id, required: is_required(o), - value: value + value: initial_value }, nodeRef); dojo.event.connect(w, @@ -303,11 +308,20 @@ function load_body(body, ui_element_stack) var initial_value = get_initial_value(o); if (get_type(o) == "boolean") { + initial_value = initial_value || false; var w = dojo.widget.createWidget("CheckBox", { - checked: initial_value + widgetId: o.getAttribute('id'), + checked: initial_value }, nodeRef); + dojo.event.connect(w, + "onClick", + function(event) + { + setXFormsValue(w.widgetId, w.checked); + }); + } else if (values.length <= 5) { @@ -444,7 +458,10 @@ function get_initial_value(o) else if (element_name == '.') break; node = node.getElementsByTagName(element_name)[0]; - dojo.debug("got node " + node.nodeName); + if (node) + dojo.debug("got node " + node.nodeName); + else + return null; } return dojo.dom.textContent(node); }