/*
* (c) Copyright 2010-2011 AgileBirds
*
* This file is part of OpenFlexo.
*
* OpenFlexo 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.
*
* OpenFlexo 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 OpenFlexo. If not, see <http://www.gnu.org/licenses/>.
*
*/
package org.openflexo.dg.docx;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Pattern;
import org.apache.velocity.VelocityContext;
import org.openflexo.antar.binding.AbstractBinding.BindingEvaluationContext;
import org.openflexo.antar.binding.BindingVariable;
import org.openflexo.dg.latex.DocGeneratorConstants;
import org.openflexo.dg.rm.DocxXmlFileResource;
import org.openflexo.foundation.FlexoModelObject;
import org.openflexo.foundation.cg.CGSymbolicDirectory;
import org.openflexo.foundation.cg.DGRepository;
import org.openflexo.foundation.cg.generator.IFlexoResourceGenerator;
import org.openflexo.foundation.dkv.DKVModel;
import org.openflexo.foundation.dm.DMModel;
import org.openflexo.foundation.dm.eo.DMEOEntity;
import org.openflexo.foundation.ie.IEPageComponent;
import org.openflexo.foundation.ie.IEPopupComponent;
import org.openflexo.foundation.ie.IETabComponent;
import org.openflexo.foundation.ie.menu.FlexoNavigationMenu;
import org.openflexo.foundation.ontology.EditionPatternInstance;
import org.openflexo.foundation.rm.cg.CGRepositoryFileResource;
import org.openflexo.foundation.toc.ConditionalSection;
import org.openflexo.foundation.toc.IterationSection;
import org.openflexo.foundation.toc.ModelObjectSection;
import org.openflexo.foundation.toc.PredefinedSection;
import org.openflexo.foundation.toc.TOCEntry;
import org.openflexo.foundation.view.View;
import org.openflexo.foundation.wkf.FlexoProcess;
import org.openflexo.foundation.wkf.node.AbstractActivityNode;
import org.openflexo.foundation.wkf.node.OperationNode;
import org.openflexo.generator.Generator;
import org.openflexo.generator.exception.GenerationException;
import org.openflexo.generator.exception.UnexpectedExceptionOccuredException;
import org.openflexo.localization.Language;
import org.openflexo.logging.FlexoLogger;
public class DGDocxXMLGenerator<T extends FlexoModelObject> extends Generator<T, DGRepository> implements IFlexoResourceGenerator,
BindingEvaluationContext {
protected static final String BAD_CHARACTERS_REG_EXP = "['\"&}%#~\\s_?+:/\\\\]";
protected static final Pattern BAD_CHARACTERS_PATTERN = Pattern.compile(BAD_CHARACTERS_REG_EXP);
protected static final Logger logger = FlexoLogger.getLogger(DGDocxXMLGenerator.class.getPackage().getName());
private String identifier;
private LinkedHashMap<DocxXmlFileResource<DGDocxXMLGenerator<T>>, DocxTemplatesEnum> docxResources;
public DGDocxXMLGenerator(ProjectDocDocxGenerator projectGenerator, T source, String identifier) {
super(projectGenerator, source);
this.docxResources = new LinkedHashMap<DocxXmlFileResource<DGDocxXMLGenerator<T>>, DocxTemplatesEnum>();
this.identifier = identifier;
}
public CGSymbolicDirectory getSymbolicDirectory(DGRepository repository) {
return repository.getDocxSymbolicDirectory();
}
@Override
public GeneratedDocxXmlResource getGeneratedCode() {
if (generatedCode == null) {
GeneratedDocxXmlResource generatedCodeTmp = new GeneratedDocxXmlResource(getIdentifier());
for (DocxXmlFileResource<DGDocxXMLGenerator<T>> resource : docxResources.keySet()) {
if (resource.getASCIIFile() == null || !resource.getASCIIFile().hasLastAcceptedContent()) {
generatedCodeTmp = null;
break;
}
generatedCodeTmp.addCode(getDocxTemplateForResource(resource), resource.getASCIIFile().getLastAcceptedContent());
}
generatedCode = generatedCodeTmp;
}
return (GeneratedDocxXmlResource) generatedCode;
}
@Override
public void buildResourcesAndSetGenerators(DGRepository repository, Vector<CGRepositoryFileResource> resources) {
getProjectGenerator().refreshConcernedResources();
}
@Override
public void generate(boolean forceRegenerate) {
if (!forceRegenerate && !needsGeneration()) {
return;
}
startGeneration();
try {
VelocityContext context = defaultContext();
generatedCode = new GeneratedDocxXmlResource(getIdentifier());
for (DocxXmlFileResource<DGDocxXMLGenerator<T>> resource : docxResources.keySet()) {
((GeneratedDocxXmlResource) generatedCode).addCode(getDocxTemplateForResource(resource),
merge(getTemplateNameForResource(resource), context));
}
} catch (GenerationException e) {
setGenerationException(e);
} catch (Exception e) {
if (logger.isLoggable(Level.WARNING)) {
logger.warning("Unexpected exception occured: " + e.getMessage() + " for " + getObject().getFullyQualifiedName());
}
e.printStackTrace();
setGenerationException(new UnexpectedExceptionOccuredException(e, getProjectGenerator()));
}
stopGeneration();
}
private VelocityContext context;
@Override
protected VelocityContext defaultContext() {
context = super.defaultContext();
context.put("DocSection", PredefinedSection.PredefinedSectionType.class);
context.put("Language", Language.class);
return context;
}
public VelocityContext getVelocityContext() {
return context;
}
@Override
public Logger getGeneratorLogger() {
return logger;
}
@Override
public String getIdentifier() {
return identifier;
}
public void addDocxResource(DocxXmlFileResource<DGDocxXMLGenerator<T>> docxResource, DocxTemplatesEnum docxTemplate) {
docxResources.put(docxResource, docxTemplate);
}
public DocxTemplatesEnum getDocxTemplateForResource(DocxXmlFileResource<DGDocxXMLGenerator<T>> docxResource) {
return docxResources.get(docxResource);
}
public String getGenerationResultKeyForResource(DocxXmlFileResource<DGDocxXMLGenerator<T>> docxResource) {
return docxResources.get(docxResource).toString();
}
public String getFileNameForResource(DocxXmlFileResource<DGDocxXMLGenerator<T>> docxResource) {
return docxResources.get(docxResource).getFilePath();
}
public String getTemplateNameForResource(DocxXmlFileResource<DGDocxXMLGenerator<T>> docxResource) {
return docxResources.get(docxResource).getTemplatePath();
}
public static String getReference(Object object) {
String s = "";
if (object instanceof FlexoProcess) {
s = "PROCESS-" + ((FlexoProcess) object).getName();
} else if (object instanceof DMModel) {
s = "DMMODEL-" + ((DMModel) object).getName();
} else if (object instanceof DMEOEntity) {
s = "DMEOENTITY-" + ((DMEOEntity) object).getName();
} else if (object instanceof AbstractActivityNode) {
s = "ACTIVITY-" + ((AbstractActivityNode) object).getName() + "-" + ((FlexoModelObject) object).getFlexoID();
} else if (object instanceof OperationNode) {
s = "OPERATION-" + ((OperationNode) object).getName() + "-" + ((FlexoModelObject) object).getFlexoID();
} else if (object instanceof DKVModel) {
s = "DKVMODEL-" + ((DKVModel) object).getName();
} else if (object instanceof FlexoNavigationMenu) {
s = "MENU-" + ((FlexoNavigationMenu) object).getName();
} else if (object instanceof IEPopupComponent) {
s = "POPUP-" + ((IEPopupComponent) object).getName();
} else if (object instanceof IETabComponent) {
s = "TAB-" + ((IETabComponent) object).getName();
} else if (object instanceof IEPageComponent) {
s = "PAGE-" + ((IEPageComponent) object).getName();
} else if (object instanceof EditionPatternInstance) {
s = ((EditionPatternInstance) object).getPattern().getName() + "-" + ((EditionPatternInstance) object).getInstanceId();
} else if (object instanceof FlexoModelObject) {
s = ((FlexoModelObject) object).getFullyQualifiedName();
} else if (object instanceof View) {
s = "VIEW-" + ((View) object).getName();
} else {
s = object.getClass().getName();
}
return getValidReference(DocGeneratorConstants.DG_LABEL_PREFIX + s);
}
public static String getValidReference(String label) {
return BAD_CHARACTERS_PATTERN.matcher(label).replaceAll("-");
}
public void beginTocEntry(TOCEntry tocEntry) {
logger.info("BEGIN TOCEntry " + tocEntry.getClass().getSimpleName() + " : " + tocEntry);
if (tocEntry instanceof IterationSection) {
IterationSection iteration = (IterationSection) tocEntry;
logger.info("Iteration " + iteration);
}
}
public void endTocEntry(TOCEntry tocEntry) {
logger.info("END TOCEntry " + tocEntry.getClass().getSimpleName() + " : " + tocEntry);
if (tocEntry instanceof IterationSection) {
IterationSection iteration = (IterationSection) tocEntry;
logger.info("Iteration " + iteration);
getVelocityContext().remove(iteration.getIteratorName());
}
}
public List<Object> getIterableObjects(IterationSection iteration) {
Object listValue = iteration.getIteration().getBindingValue(this);
logger.info("getIterableObjects = " + listValue);
if (listValue instanceof List) {
return (List) listValue;
}
return null;
}
public Object iterateOnItem(IterationSection iteration, Object item) {
logger.info("> Iterate on item " + item + " of " + item.getClass().getSimpleName());
getVelocityContext().put(iteration.getIteratorName(), item);
return item;
}
public Boolean getItemCondition(IterationSection iteration) {
if (!iteration.getCondition().isSet() || !iteration.getCondition().isValid()) {
return true;
}
Object conditionValue = iteration.getCondition().getBindingValue(this);
logger.info("conditionValue = " + conditionValue);
return (Boolean) conditionValue;
}
public Boolean getCondition(ConditionalSection conditional) {
if (!conditional.getCondition().isSet() || !conditional.getCondition().isValid()) {
return true;
}
Object conditionValue = conditional.getCondition().getBindingValue(this);
logger.info("conditionValue = " + conditionValue);
return (Boolean) conditionValue;
}
public FlexoModelObject getAccessedModelObject(TOCEntry section) {
if (section instanceof ModelObjectSection<?>) {
return getAccessedModelObject((ModelObjectSection<?>) section);
} else if (section.getObject() != null) {
return section.getObject();
} else if (section.getIdentifier() != null) {
switch (section.getIdentifier()) {
case DATA_MODEL:
return getProject().getDataModel();
case PROCESSES:
return getProject().getWorkflow();
case ROLES:
return getProject().getWorkflow().getRoleList();
case SCREENS:
return getProject().getFlexoComponentLibrary();
case VIEWS:
return getProject().getShemaLibrary();
}
}
if (logger.isLoggable(Level.SEVERE)) {
logger.severe("getAccessedModelObject invoked with a section that does not have an associated object: \"" + section.getTitle()
+ "\". Returning null that will probably create NPE");
}
return null;
}
private <T extends FlexoModelObject> T getAccessedModelObject(ModelObjectSection<T> section) {
if (section.getObject() != null) {
return (T) section.getObject();
}
if (!section.getValue().isSet() || !section.getValue().isValid()) {
return null;
}
Object objectValue = section.getValue().getBindingValue(this);
logger.info("objectValue = " + objectValue);
return (T) objectValue;
}
@Override
public Object getValue(BindingVariable variable) {
if (getVelocityContext() != null) {
System.out.println("For value " + variable.getVariableName() + " return "
+ getVelocityContext().get(variable.getVariableName()));
return getVelocityContext().get(variable.getVariableName());
}
return null;
}
}