Java tutorial
/* Copyright (C) 2007-2011 BlueXML - www.bluexml.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.bluexml.xforms.generator.forms; import java.io.File; import java.io.FileOutputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeMap; import java.util.TreeSet; import java.util.Map.Entry; import org.apache.commons.lang.StringUtils; import org.eclipse.emf.common.util.EList; import org.jdom.Document; import org.jdom.Element; import org.jdom.Namespace; import org.jdom.input.SAXBuilder; import org.jdom.output.Format; import org.jdom.output.XMLOutputter; import com.bluexml.side.clazz.Aspect; import com.bluexml.side.clazz.Association; import com.bluexml.side.clazz.Attribute; import com.bluexml.side.clazz.Clazz; import com.bluexml.side.clazz.Enumeration; import com.bluexml.side.clazz.EnumerationLiteral; import com.bluexml.side.form.FormClass; import com.bluexml.side.form.FormContainer; import com.bluexml.side.form.FormGroupPresentationType; import com.bluexml.side.form.FormSearch; import com.bluexml.side.form.FormWorkflow; import com.bluexml.side.form.impl.FormGroupImpl; import com.bluexml.xforms.generator.AbstractGenerator; import com.bluexml.xforms.generator.SearchOperator; import com.bluexml.xforms.generator.forms.modelelement.ModelElementBindSimple; import com.bluexml.xforms.generator.forms.renderable.RenderableXForm; import com.bluexml.xforms.generator.forms.renderable.classes.RenderableClass; import com.bluexml.xforms.generator.forms.renderable.classes.RenderableClassSelector; import com.bluexml.xforms.generator.forms.renderable.common.RenderableDiv; import com.bluexml.xforms.generator.forms.renderable.common.RenderableHR; import com.bluexml.xforms.generator.forms.renderable.common.RenderableXGroup; import com.bluexml.xforms.generator.forms.renderable.forms.field.RenderableFileInputForContent; import com.bluexml.xforms.generator.forms.renderable.forms.group.RenderableFormContainer; import com.bluexml.xforms.generator.forms.renderable.lists.RenderableClassList; import com.bluexml.xforms.generator.forms.rendered.RenderedParentGroup; import com.bluexml.xforms.generator.tools.ClasseComparator; import com.bluexml.xforms.generator.tools.ModelTools; import com.bluexml.xforms.messages.MsgId; /** * The Class XFormsGenerator. */ public class XFormsGenerator extends AbstractGenerator { @Deprecated class IntGroupImpl extends FormGroupImpl { String id; String label; public IntGroupImpl(String id, String label) { this.id = id; this.label = label; } @Override public FormGroupPresentationType getPresentation() { return FormGroupPresentationType.AUTO; } @Override public String getLabel() { return label; } @Override public String getId() { return id; } } /** The Constant NAMESPACE_EVENTS. */ public static final Namespace NAMESPACE_EVENTS = Namespace.getNamespace("ev", "http://www.w3.org/2001/xml-events"); /** The Constant NAMESPACE_XFORMS. */ public static final Namespace NAMESPACE_XFORMS = Namespace.getNamespace("xf", "http://www.w3.org/2002/xforms"); /** The Constant NAMESPACE_XHTML. */ public static final Namespace NAMESPACE_XHTML = Namespace.getNamespace("xhtml", "http://www.w3.org/1999/xhtml"); public static final String IMG_ADD = "resources/images/add.png"; public static final String IMG_REMOVE = "resources/images/remove.png"; public static final String IMG_RIGHT = "resources/images/right.png"; public static final String IMG_LEFT = "resources/images/left.png"; public static final String IMG_DOWN = "resources/images/down.png"; public static final String IMG_UP = "resources/images/up.png"; // ** #1530 public static final String IMG_SELECT = "resources/images/select.png"; public static final String IMG_DESELECT = "resources/images/deselect.png"; // ** public static final String IMG_CLEAR = "resources/images/clear.png"; public static final String IMG_SEARCH = "resources/images/search.png"; /** The sax builder. */ public static SAXBuilder saxBuilder; /** The outputter. */ public static XMLOutputter outputter; /** The keys. */ private static Map<String, Set<String>> keys = new HashMap<String, Set<String>>(); /** The general keys. */ private static Map<String, Set<String>> generalKeys = new HashMap<String, Set<String>>(); static { saxBuilder = new SAXBuilder(); outputter = new XMLOutputter(Format.getPrettyFormat()); } /** The output xforms folder. */ private File outputXForms; /** The classes. */ private Map<Clazz, RenderableClass> classes = new TreeMap<Clazz, RenderableClass>(ClasseComparator.INSTANCE); /** The formsRenderables, with their renderable versions. */ private Map<String, RenderableFormContainer> formsRenderables = new HashMap<String, RenderableFormContainer>(); /** The formsRenderables, with their original version. */ private Map<String, FormContainer> formsModels = new HashMap<String, FormContainer>(); private Set<FormTypeRendered> formTypesToDescribe; private static boolean renderingWorkflow; /** * Creates a DOM element. * * @param tagName * the tag name * @param namespace * the namespace * * @return the element */ public static Element createElement(String tagName, Namespace namespace) { return new Element(tagName, namespace); } /** * Creates a DOM element with content. * * @param tagName * the tag name * @param namespace * the namespace * @param content * the content * * @return the element */ public static Element createElementWithContent(String tagName, Namespace namespace, String content) { Element createdElement = createElement(tagName, namespace); createdElement.setText(content); return createdElement; } /** * Creates a DOM element with label. * * @param tagName * the tag name * @param namespace * the namespace * @param label * the label * * @return the element */ public static Element createElementWithLabel(String tagName, Namespace namespace, String label) { Element element = createElement(tagName, namespace); Element labelElement = createElementWithContent("label", NAMESPACE_XFORMS, label); element.addContent(labelElement); return element; } /** * Creates a trigger with label image. * * @param image * the image * * @return the element */ public static Element createTriggerWithLabelImage(String image, String altText) { Element element = createElement("trigger", NAMESPACE_XFORMS); element.setAttribute("appearance", "minimal"); Element labelElement = createElement("label", NAMESPACE_XFORMS); Element imageElement = createElement("img", NAMESPACE_XHTML); imageElement.setAttribute("border", "0"); imageElement.setAttribute("src", image); imageElement.setAttribute("alt", altText); labelElement.addContent(imageElement); element.addContent(labelElement); return element; } /** * Creates a xforms group. * * @param label * the label * @param style * the CSS class if applicable. May be <code>null</code>. * * @return the element */ public static Element createXFormsGroup(String label, String style) { Element group = XFormsGenerator.createElementWithLabel("group", NAMESPACE_XFORMS, label); group.setAttribute("appearance", "full"); if (style != null) { group.setAttribute("class", style); } return group; } /** * Gets the nth bind. * * @param parentRendered * the parent rendered * @param nth * the nth * * @return the bind */ public static ModelElementBindSimple getBind(Rendered parentRendered, int nth) { List<ModelElement> modelElements = new ArrayList<ModelElement>(parentRendered.getModelElements()); // search also in parent binds if parent is a group if (parentRendered instanceof RenderedParentGroup) { modelElements.addAll(((RenderedParentGroup) parentRendered).getParent().getModelElements()); } int i = 0; for (ModelElement modelElement : modelElements) { if (modelElement instanceof ModelElementBindSimple) { i++; if (i == nth) { return (ModelElementBindSimple) modelElement; } } } throw new RuntimeException(new NullPointerException()); } /** * Gets an id. * * @param id * the id * * @return the id */ public static String getId(String id) { Set<String> list = keys.get(id); if (list == null) { list = new HashSet<String>(); list.add(id); keys.put(id, list); return id; } int i = 0; String nid = null; do { i++; nid = id + "-" + i; } while (list.contains(nid)); list.add(nid); return nid; } /** * Gets the general id. * * @param id * the id * * @return the general id */ public static String getGeneralId(String id) { Set<String> list = generalKeys.get(id); if (list == null) { list = new HashSet<String>(); list.add(id); generalKeys.put(id, list); return id; } int i = 0; String nid = null; do { i++; nid = id + "-" + i; } while (list.contains(nid)); list.add(nid); return nid; } /** * Reset keys. */ public static void resetKeys() { keys = new HashMap<String, Set<String>>(); } /* * (non-Javadoc) * * @see com.bluexml.xforms.generator.DataGenerator#addAspectForClass(com.bluexml * .side.clazz.Clazz, com.bluexml.side.clazz.Aspect, com.bluexml.side.clazz.Clazz) */ public void addAspectForClass(Clazz classe, Aspect aspect, Clazz owner) { getClassBean(classe).addAspect(aspect); } /** * Adds the association. * * @param type * the type * @param name * the name * @param title * the title * @param source * the source * @param destination * the destination * @param doublenav * the doublenav * @param association * the association */ private void addAssociation(AssociationKind type, String name, String title, Clazz source, Clazz destination, Association association) { RenderableClass classBeanSource = getClassBean(source); RenderableClass classBeanDestination = getClassBean(destination); try { classBeanSource.addAssociation(source, destination, classBeanDestination, name, title, type, association); } catch (NullPointerException e) { // nothing to do if in dev mode if (formGenerator.isDebugMode() == false) { throw (e); } } } /* * (non-Javadoc) * * @see com.bluexml.xforms.generator.DataGenerator#addAssociation(org.blueXML * .xforms.generator.DataGenerator.AssociationKind, java.lang.String, java.lang.String, * com.bluexml.side.clazz.Clazz, com.bluexml.side.clazz.Clazz, java.lang.String, boolean, * com.bluexml.side.clazz.Association, com.bluexml.side.clazz.Clazz) */ public void addAssociation(AssociationKind type, String name, String title, Clazz source, Clazz destination, String role, boolean doublenav, Association association, Clazz owner) { addAssociation(type, name, title, source, destination, association); } /* * (non-Javadoc) * * @see com.bluexml.xforms.generator.DataGenerator#addAttributeForAspect(com. * bluexml.side.clazz.Aspect, com.bluexml.side.clazz.Attribute) */ public void addAttributeForAspect(Aspect aspect, Attribute attribute) { // nothing } /** * Adds the attribute for class. * * @param classe * the classe * @param attribute * the attribute */ public void addAttributeForClass(Clazz classe, Attribute attribute) { getClassBean(classe).addAttribute(attribute); } /* * (non-Javadoc) * * @see com.bluexml.xforms.generator.DataGenerator#addAttributeForClass(com.bluexml * .side.clazz.Clazz, com.bluexml.side.clazz.Attribute, com.bluexml.side.clazz.Clazz) */ public void addAttributeForClass(Clazz classe, Attribute attribute, Clazz owner) { addAttributeForClass(classe, attribute); } /* * (non-Javadoc) * * @see com.bluexml.xforms.generator.DataGenerator#addIdForClass(com.bluexml. side.clazz.Clazz, * java.lang.String, boolean) */ // public void addIdForClass(Clazz classe, String string, boolean hasParent) { // addIdForClass(classe, string); // } /* * (non-Javadoc) * * @see com.bluexml.xforms.generator.DataGenerator#beginAspect(com.bluexml.side .clazz.Aspect) */ public void beginAspect(Aspect aspect) { // nothing } /* * (non-Javadoc) * * @see com.bluexml.xforms.generator.DataGenerator#beginClasse(com.bluexml.side .clazz.Clazz, * boolean) */ public void beginClasse(Clazz classe, boolean rendered) { RenderableClass classeBean = null; classeBean = new RenderableClass(classe, rendered); classes.put(classe, classeBean); } /* * (non-Javadoc) * * @see * com.bluexml.xforms.generator.DataGenerator#beginForm(com.bluexml.side.form.FormContainer) */ public void beginForm(FormContainer form) { FormContainer realContainer = form; realContainer = (FormContainer) formGenerator.getRealObject(form); // #1225 RenderableFormContainer renForm = new RenderableFormContainer(this, null, realContainer); formsRenderables.put(realContainer.getId(), renForm); formsModels.put(realContainer.getId(), realContainer); } /* * (non-Javadoc) * * @see com.bluexml.xforms.generator.DataGenerator#beginGeneration() */ public void beginGeneration() { if (monitor != null) { monitor.setTaskName("Generation of XHTML templates."); } if (isReadOnlyMode()) { monitor.addText("Generating XHTML templates (Read Only)."); } else { monitor.addText("Generating XHTML templates."); } formTypesToDescribe = new TreeSet<FormTypeRendered>(); } /* * (non-Javadoc) * * @see com.bluexml.xforms.generator.DataGenerator#beginListAspects() */ public void beginListAspects() { // nothing } /* * (non-Javadoc) * * @see com.bluexml.xforms.generator.DataGenerator#beginListAssociations() */ public void beginListAssociations() { // nothing } /* * (non-Javadoc) * * @see com.bluexml.xforms.generator.DataGenerator#beginListClasses() */ public void beginListClasses() { // nothing } /* * (non-Javadoc) * * @see com.bluexml.xforms.generator.DataGenerator#beginListEnums() */ public void beginListEnums() { // nothing } /* * (non-Javadoc) * * @see com.bluexml.xforms.generator.DataGenerator#beginListForms() */ public void beginListForms() { // nothing } /* * (non-Javadoc) * * @see com.bluexml.xforms.generator.DataGenerator#endAspect(com.bluexml.side .clazz.Aspect) */ public void endAspect(Aspect aspect) { // nothing } /* * (non-Javadoc) * * @see com.bluexml.xforms.generator.DataGenerator#endClasse(com.bluexml.side .clazz.Clazz) */ public void endClasse(Clazz classe) { // nothing } /* * (non-Javadoc) * * @see com.bluexml.xforms.generator.DataGenerator#endForm(com.bluexml.side.form .Form) */ public void endForm(FormContainer form) { // nothing } /* * (non-Javadoc) * * @see com.bluexml.xforms.generator.DataGenerator#endGeneration() */ public void endGeneration() { renderAllClasses(); renderAllForms(); if (formGenerator.isSearchCapable()) { renderSearchOperatorsEnums(); } renderDescriptionFiles(); monitor.addText("XFormGenerator: Finished generating XHTML templates."); } /** * Writes the files containing the search operators enumerations. */ private void renderSearchOperatorsEnums() { Map<String, List<SearchOperator>> opEnumsMap = formGenerator.getOperatorsEnumsMap(); for (Entry<String, List<SearchOperator>> entry : opEnumsMap.entrySet()) { renderSearchOperatorsEnumFile(entry.getKey(), entry.getValue()); } } /** * Writes the file that will provide a specific set of operators at runtime. * * @param opKey * the identifier for the set of operators * @param opList * the list of operators in this set */ private void renderSearchOperatorsEnumFile(String opKey, List<SearchOperator> opList) { // // the list is normally sorted so no need to sort it again Element racineEnums = new Element("enums"); Document documentEnums = new Document(racineEnums); for (SearchOperator operator : opList) { Element l = new Element(MsgId.INT_INSTANCE_SELECT_ITEM.getText()); Element name = new Element(MsgId.INT_INSTANCE_ENUM_ID.getText()); name.setText(operator.getId()); l.addContent(name); Element value = new Element(MsgId.INT_INSTANCE_ENUM_VALUE.getText()); value.setText(operator.getLabel()); l.addContent(value); racineEnums.addContent(l); } String fileName = MsgId.INT_PREFIX_FILENAME_OPERATORS + opKey + ".enum.xml"; String pathname = outputXForms.getAbsolutePath() + File.separator + MsgId.INT_DIRECTORY_ENUMS + File.separator; File parentDir = new File(pathname); parentDir.mkdirs(); File file = new File(pathname + fileName); try { FileOutputStream fos = new FileOutputStream(file); outputter.output(documentEnums, fos); fos.close(); } catch (Exception ex) { monitor.addErrorTextAndLog("Could not write file " + file.getAbsolutePath(), ex, null); } } /** * Writes the description files into the directories of each form type that's been generated. */ private void renderDescriptionFiles() { Element root = new Element("root"); Document doc = new Document(root); Element labelElt = new Element("label"); root.addContent(labelElt); Element descrElt = new Element("description"); root.addContent(descrElt); for (FormTypeRendered formType : formTypesToDescribe) { StringBuffer fileName = new StringBuffer(outputXForms.getAbsolutePath()); fileName.append(File.separatorChar); fileName.append(formType.getFolder()); if (StringUtils.trimToNull(formType.getFolder()) != null) { fileName.append(File.separatorChar); } fileName.append("descr.xml"); File descrFile = new File(fileName.toString()); if (StringUtils.trimToNull(formType.getLabel()) != null) { labelElt.setText(formType.getLabel()); descrElt.setText(formType.getDescription()); try { FileOutputStream fos = new FileOutputStream(descrFile); outputter.output(doc, fos); fos.close(); } catch (Exception ex) { monitor.addErrorTextAndLog( "Could not write folder description file " + descrFile.getAbsolutePath(), null, null); } } } } /** * */ private void renderAllClasses() { monitor.addText("Rendering default forms"); Set<Entry<Clazz, RenderableClass>> entrySet = classes.entrySet(); for (Entry<Clazz, RenderableClass> entry : entrySet) { Clazz classe = entry.getKey(); monitor.addText(" class: " + ModelTools.getCompleteName(classe)); RenderableClass classeBean = entry.getValue(); if (classeBean.isToRender()) { String formName = ModelTools.getCompleteName(classe); String title = ModelTools.getTitle(classe); if (!classe.isAbstract()) { render(outputXForms, classeBean, formName, title, FormTypeRendered.formClass, false); if (formGenerator.isGenerateLogListForms()) { render(outputXForms, new RenderableClassList(classe), formName, title, FormTypeRendered.formClassList, false); } } if (classeBean.hasSubClasses()) { render(outputXForms, new RenderableClassSelector(classeBean.getSubClasses()), formName, title, FormTypeRendered.formClassSubClassSelector, false); } } } } /** * Renders all modeled forms and sets/keeps relevant information about each type of FormXXX. * * @return true if there is one or more workflow forms */ private void renderAllForms() { monitor.addText("Rendering customized forms"); Set<Entry<String, RenderableFormContainer>> entrySetForms = formsRenderables.entrySet(); for (Entry<String, RenderableFormContainer> formEntry : entrySetForms) { String formId = formEntry.getKey(); FormContainer formContainer = formsModels.get(formId); String title = formsModels.get(formId).getLabel(); boolean isContentEnabled = false; FormTypeRendered formTypeRendered = null; String logPrefix = ""; if (formContainer instanceof FormWorkflow) { formGenerator.setWorkflowCapable(true); formTypeRendered = FormTypeRendered.formWkflw; logPrefix = "FormWorkflow"; } else if (formContainer instanceof FormClass) { isContentEnabled = ((FormClass) formContainer).isContent_enabled(); formTypeRendered = FormTypeRendered.formForm; logPrefix = "FormClass"; } else if (formContainer instanceof FormSearch) { formGenerator.setSearchCapable(true); formTypeRendered = FormTypeRendered.formSearch; logPrefix = "FormSearch"; } else { // normally, we never reach here. } if (formGenerator.isDebugMode()) { String logText = " " + logPrefix + ": " + formId; monitor.addText(logText); } RenderableFormContainer rfc = formEntry.getValue(); render(outputXForms, rfc, formId, title, formTypeRendered, isContentEnabled); } } /** * Generates the form for selecting a process definition. */ @SuppressWarnings("unused") @Deprecated private void renderWorkflowSelectionForm() { // // // IntGroupImpl fglobalGroup = new IntGroupImpl("workflow", MsgPool // .getMsg(MsgId.MSG_WKFLW_GLOBAL_GROUP)); // RenderableGroup<FormGroup> rglobalGroup = new RenderableGroup<FormGroup>(this, null, // fglobalGroup); // // // IntGroupImpl fprocessGroup = new IntGroupImpl(MsgId.INT_WKFLW_PROCESS_NODESET.getText(), // MsgPool.getMsg(MsgId.MSG_WKFLW_PROCESS_GROUP)); // RenderableGroupWorkflow<FormGroup> rprocessGroup = new // RenderableGroupWorkflow<FormGroup>( // this, fglobalGroup, fprocessGroup); // // Renderable processList = newWorkflowSelectionWidget(true); // rprocessGroup.add(processList); // rglobalGroup.add(rprocessGroup); // // // IntGroupImpl finstanceGroup = new // IntGroupImpl(MsgId.INT_WKFLW_INSTANCE_NODESET.getText(), // MsgPool.getMsg(MsgId.MSG_WKFLW_INSTANCE_GROUP)); // RenderableGroupWorkflow<FormGroup> rinstanceGroup = new // RenderableGroupWorkflow<FormGroup>( // this, fglobalGroup, finstanceGroup); // // Renderable instanceList = newWorkflowSelectionWidget(false); // rinstanceGroup.add(instanceList); // rglobalGroup.add(rinstanceGroup); // render(outputXForms, rglobalGroup, MsgId.INT_WKFLW_SEL_FORM_FILENAME.getText(), MsgPool // .getMsg(MsgId.MSG_WKFLW_SEL_PAGE_TITLE), FormTypeRendered.formWkflwSel, false); } /** * Builds the widget for selecting process definitions * * @param renderedParent */ @SuppressWarnings("unused") @Deprecated private Renderable newWorkflowSelectionWidget(boolean isProcess) { // String nodeset; // MsgId widgetTitle; // String groupName; // // if (isProcess) { // nodeset = MsgId.INT_WKFLW_PROCESS_NODESET.getText(); // widgetTitle = MsgId.MSG_WKFLW_PROCESS_WIDGET_TITLE; // groupName = "workflow_definitions"; // } else { // nodeset = MsgId.INT_WKFLW_PROCESS_NODESET.getText(); // widgetTitle = MsgId.MSG_WKFLW_INSTANCE_WIDGET_TITLE; // groupName = "workflow_instances"; // } // SelectBean selectBean = new SelectBean(); // ModelElementBindSimple meb = new ModelElementBindSimple(MsgId.INT_WKFLW_NODESET_PREFIX // .getText() // + "/" + nodeset); // // selectBean.setEnumeration(null); // selectBean.setEnumContext(null); // selectBean.setEnumParent(null); // selectBean.setWidgetType(ChoiceWidgetType.SHOW_ONE); // selectBean.setLabel(MsgPool.getMsg(widgetTitle)); // selectBean.setModelElementBindSimple(meb); // selectBean.setMultiple(false); // selectBean.setLimited(false); // // AssociationBean associationBean = new AssociationBean(); // // associationBean.setForWorkflow(true); // associationBean.setCreateEditForm(null); // associationBean.setDestinationRenderable(null); // if (isProcess) { // associationBean.setDestinationProcessSelect(selectBean); // } else { // associationBean.setDestinationInstanceSelect(selectBean); // } // associationBean.setName(groupName); // associationBean.setShowingActions(false); // associationBean.setFieldSize("0"); // // RenderableSelector selector = new RenderableSelector(associationBean); // RenderableSSingle renderable = new RenderableSSingle(associationBean, selector); // return renderable; return null; } /* * (non-Javadoc) * * @see com.bluexml.xforms.generator.DataGenerator#endListAspects() */ public void endListAspects() { // nothing } /* * (non-Javadoc) * * @see com.bluexml.xforms.generator.DataGenerator#endListAssociations() */ public void endListAssociations() { // nothing } /* * (non-Javadoc) * * @see com.bluexml.xforms.generator.DataGenerator#endListClasses() */ public void endListClasses() { Set<Entry<Clazz, RenderableClass>> entrySet = classes.entrySet(); for (Entry<Clazz, RenderableClass> entry : entrySet) { addGeneralizations(entry.getKey(), entry.getKey()); } } /* * (non-Javadoc) * * @see com.bluexml.xforms.generator.DataGenerator#endListEnums() */ public void endListEnums() { // nothing } /* * (non-Javadoc) * * @see com.bluexml.xforms.generator.DataGenerator#endListForms() */ public void endListForms() { Set<Entry<String, RenderableFormContainer>> entrySet = formsRenderables.entrySet(); // System.out.println("listing formsRenderables ---"); // for (FormContainer entry : formsRenderables.keySet()) { // System.out.println(entry.getId()); // } // System.out.println("-----------------"); // // deal with FormClass's first for (Entry<String, RenderableFormContainer> entry : entrySet) { FormContainer FC = formsModels.get(entry.getKey()); if ((FC instanceof FormClass) || (FC instanceof FormSearch)) { RenderableFormContainer renderableFC = entry.getValue(); renderableFC.compute(); } } // for (Entry<String, RenderableFormContainer> entry : entrySet) { FormContainer FC = formsModels.get(entry.getKey()); if (FC instanceof FormWorkflow) { RenderableFormContainer renderableFC = entry.getValue(); // add all form elements defined in the form editor renderableFC.compute(); // FormWorkflow FW = ((FormWorkflow) FC); FormClass dataForm = FW.getDataForm(); if (dataForm != null) { RenderableFormContainer attached = searchForForm(dataForm); if (attached == null) { throw new RuntimeException("Workflow Form '" + FW.getId() + "' has no attached data form. Id of DataForm: " + dataForm.getId()); } // TODO: clone the attached renderable if (formGenerator.isRenderDataBeforeWorkflow()) { renderableFC.addFirst(new RenderableHR()); renderableFC.addFirst(attached); } else { renderableFC.add(new RenderableHR()); renderableFC.add(attached); } } } } } /** * Finds in the map <b>formsRenderables</b> the renderable element attached to a form class.<br/> * This function is made necessary by the fact that formsRenderables.get(dataForm) is apparently * unable to find dataForm when the referenced FormClass object is from a file distinct from the * workflow form's file: it returns null in those cases. * * @param dataForm * the form class * @return */ private RenderableFormContainer searchForForm(FormClass dataForm) { for (Entry<String, RenderableFormContainer> entry : formsRenderables.entrySet()) { FormContainer key = formsModels.get(entry.getKey()); if (key instanceof FormClass) { FormClass fcl = (FormClass) key; if (fcl.getId().equals(dataForm.getId())) { return entry.getValue(); } } } return null; } /** * Gets the class bean. * * @param classe * the classe * * @return the class bean */ public RenderableClass getClassBean(Clazz classe) { RenderableClass renderableClass = classes.get(classe); if (renderableClass == null) { String completeName = ModelTools.getCompleteName(classe); Set<Entry<Clazz, RenderableClass>> entrySet = classes.entrySet(); for (Entry<Clazz, RenderableClass> entry : entrySet) { if (ModelTools.getCompleteName(entry.getKey()).equals(completeName)) { return entry.getValue(); } } } return renderableClass; } /** * Gets the renderable form. * * @param form * the form * * @return the renderable form */ public RenderableFormContainer getRenderableForm(FormContainer form) { FormContainer realContainer = form; realContainer = (FormContainer) formGenerator.getRealObject(form); // #1225 return formsRenderables.get(realContainer.getId()); } /* * (non-Javadoc) * * @see com.bluexml.xforms.generator.DataGenerator#processEnum(com.bluexml.side * .clazz.Enumeration) */ public void processEnum(Enumeration enumeration) { int i = 1; // writes static enums into XML files, associating the enum value with a collision-free id if (!enumeration.getDynamic()) { formTypesToDescribe.add(FormTypeRendered.formEnum); Element racineEnums = new Element("enums"); Document documentEnums = new Document(racineEnums); EList<EnumerationLiteral> literals = enumeration.getLiterals(); for (EnumerationLiteral enumerationLiteral : literals) { Element l = new Element(MsgId.INT_INSTANCE_SELECT_ITEM.getText()); // order position for use with multiple selection enum fields Element idElt = new Element(MsgId.INT_INSTANCE_ENUM_ID.getText()); idElt.setText(Integer.toString(i)); i++; l.addContent(idElt); Element valueElt = new Element(MsgId.INT_INSTANCE_ENUM_VALUE.getText()); String value = enumerationLiteral.getValue(); // #1550, use value instead of name valueElt.setText(value); l.addContent(valueElt); racineEnums.addContent(l); } String fileName = ModelTools.getCompleteName(enumeration) + ".enum.xml"; String pathname = outputXForms.getAbsolutePath() + File.separator + MsgId.INT_DIRECTORY_ENUMS + File.separator; File parentDir = new File(pathname); parentDir.mkdirs(); File file = new File(pathname + fileName); try { FileOutputStream fos = new FileOutputStream(file); outputter.output(documentEnums, fos); fos.close(); } catch (Exception ex) { monitor.addErrorTextAndLog("Could not write file " + file.getAbsolutePath(), ex, null); } } } /** * Sets the output folder. * * @param xformsOutput * the new output folder */ public void setOutputFolder(String xformsOutput) { outputXForms = new File(xformsOutput); outputXForms.mkdirs(); } /** * Adds the generalizations/specializations. The information collected is useful for building * the selector forms. * * @param leafClasse * the leaf classe * @param classe * the classe */ private void addGeneralizations(Clazz leafClasse, Clazz classe) { EList<Clazz> generalizations = leafClasse.getGeneralizations(); for (Clazz generalization : generalizations) { Clazz parentClasse = generalization; if (!classe.isAbstract()) { RenderableClass parentClass = classes.get(parentClasse); if (parentClass != null) { parentClass.addSubClass(classe); } else { monitor.addErrorTextAndLog("No classType found for class '" + classe.getLabel() + "'. Please add the containing model to the generation project.", null, null); } } addGeneralizations(parentClasse, classe); } } /** * Render a FormClass or FormWorkflow. * * @param outputXForms * the output x formsRenderables * @param formId * the form * @param rFC * the form container * @param isContentEnabled * @param isWorkflowAble * whether workflows can be started on the form */ @Deprecated @SuppressWarnings("unused") private void renderForm(File outputXForms, String formId, RenderableFormContainer rFC, boolean isAWorkflowForm, boolean isContentEnabled) { String title = formsModels.get(formId).getLabel(); FormTypeRendered formTypeRendered = (isAWorkflowForm) ? FormTypeRendered.formWkflw : FormTypeRendered.formForm; render(outputXForms, rFC, formId, title, formTypeRendered, isContentEnabled); } /** * Render any renderable in a file. * * @param outputXForms * the output x formsRenderables * @param renderable * the renderable * @param formName * the form name. Sets the name of the xhtml file template. * @param classActions * the class actions. If not provided, will be built based on defaults for the form * type * @param title * the title * @param formType * the form type. CLASS, FORM, WKFLW, etc. * @param isContentEnabled * whether the file upload control should appear on the form */ private void render(File outputXForms, Renderable renderable, String formName, String title, FormTypeRendered formType, boolean isContentEnabled) { // there's no point in writing RO versions of some form types if (isReadOnlyMode()) { if (formType != FormTypeRendered.formForm && formType != FormTypeRendered.formClass) { return; } } // register this type of form for writing the descr.xml files formTypesToDescribe.add(formType); resetKeys(); // build the submission actions that are relevant for this type of form List<FormSubmissionActions> actions; actions = new ArrayList<FormSubmissionActions>(); for (FormSubmissionActions abstractAction : formType.getActions()) { actions.add(abstractAction); } // if form class, wrap the renderable in a group Renderable realRenderable = renderable; if (formType == FormTypeRendered.formClass) { realRenderable = new RenderableXGroup(renderable, title, null); realRenderable = new RenderableXGroup(realRenderable, "", MsgId.INT_CSS_FORM_TITLE_CLASS.getText()); } // if applicable, show the content upload field if (isContentEnabled) { RenderableFileInputForContent rContent = new RenderableFileInputForContent(); realRenderable.add(new RenderableHR()); realRenderable.add(rContent); } RenderableXForm form = new RenderableXForm(realRenderable, title, actions, formType); // add the status bar RenderableDiv statusDiv = new RenderableDiv(MsgId.INT_CSS_STATUS_BAR_ID.getText()); RenderableHR lineAbove = new RenderableHR(); RenderableHR lineBelow = new RenderableHR(); form.add(lineAbove); form.add(statusDiv); form.add(lineBelow); // render all elements on the form Rendered rendered = form.recursiveRender(); // write the XHTML/XForms rendering in a file StringBuffer fileName = new StringBuffer(outputXForms.getAbsolutePath()); fileName.append(File.separatorChar); fileName.append(formType.getFolder()); fileName.append(File.separatorChar); fileName.append(formName); if (isReadOnlyMode()) { fileName.append(formGenerator.getReadOnlySuffix()); } fileName.append(formType.getSuffix()); fileName.append(".xhtml"); String currentFilePath = fileName.toString(); try { File file = new File(currentFilePath); file.getParentFile().mkdirs(); Element xformsElement = rendered.getXformsElement(); Element clonedElement = (Element) xformsElement.clone(); Document newDocument = new Document(clonedElement); clonedElement.addNamespaceDeclaration(NAMESPACE_XHTML); clonedElement.addNamespaceDeclaration(NAMESPACE_XFORMS); clonedElement.addNamespaceDeclaration(NAMESPACE_EVENTS); FileOutputStream fos = new FileOutputStream(file); outputter.output(newDocument, fos); fos.close(); } catch (Exception e) { monitor.addErrorTextAndLog("Could not write form file " + currentFilePath, e, null); } } /** * @param renderingWorkflow * the renderingWorkflow to set */ public static void setRenderingWorkflow(boolean renderingWorkflow) { XFormsGenerator.renderingWorkflow = renderingWorkflow; } /** * @return the renderingWorkflow */ public static boolean isRenderingWorkflow() { return renderingWorkflow; } /* * (non-Javadoc) * * @see com.bluexml.xforms.generator.AbstractDataGenerator#isReadOnlyMode() */ @Override public boolean isReadOnlyMode() { return readOnlyMode; } /* * (non-Javadoc) * * @see com.bluexml.xforms.generator.AbstractDataGenerator#setReadOnlyMode(boolean) */ @Override public void setReadOnlyMode(boolean onOff) { this.readOnlyMode = onOff; } /* * (non-Javadoc) * * @see com.bluexml.xforms.generator.AbstractDataGenerator#supportsReadOnlyMode() */ @Override public boolean supportsReadOnlyMode() { return true; } }