blob: c0c94e25ecd1dd064044918cffd83fad3ec3ccf0 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009 David A Carlson.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* David A Carlson (XMLmodeling.com) - initial API and implementation
*
* $Id$
*******************************************************************************/
package org.eclipse.mdht.uml.cda.dita;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.mdht.uml.cda.core.util.CDACommonUtils;
import org.eclipse.mdht.uml.cda.core.util.CDAModelUtil;
import org.eclipse.mdht.uml.cda.dita.internal.Logger;
import org.eclipse.mdht.uml.common.util.UMLUtil;
import org.eclipse.uml2.uml.Class;
import org.eclipse.uml2.uml.Generalization;
import org.eclipse.uml2.uml.NamedElement;
import org.eclipse.uml2.uml.Property;
public class TransformClass extends TransformAbstract {
private Set<Class> alreadyHandled = new HashSet<Class>();
private Set<Class> alreadyHandledForPrintTerminologyConstraintAsList = new HashSet<Class>();
public TransformClass(DitaTransformerOptions options) {
super(options);
}
private void appendBody(PrintWriter writer, Class umlClass) {
String normalizedClassName = normalizeCodeName(umlClass.getName());
writer.println("<body>");
writer.println("<section conref=\"generated/_" + normalizedClassName + ".dita#classId/knownSubclasses\">");
writer.println("</section>");
writer.println("<!-- TODO: insert non-model class description markup here -->");
writer.println("<section conref=\"generated/_" + normalizedClassName + ".dita#classId/description\">");
writer.println("</section>");
writer.println(
"<section audience=\"contextTable\" conref=\"generated/_" + normalizedClassName +
".dita#classId/contextTable\">");
writer.println("</section>");
writer.println("<!-- TODO: insert UML class diagram here -->");
writer.println();
writer.println(
"<ol audience=\"standards\" conref=\"generated/_" + normalizedClassName + ".dita#classId/conformance\">");
writer.println("<li></li>");
writer.println("</ol>");
writer.println(
"<ol audience=\"developer\" conref=\"generated/_" + normalizedClassName + ".dita#classId/aggregate\">");
writer.println("<li></li>");
writer.println("</ol>");
// only generate these sections for CDA templates
Class cdaClass = CDAModelUtil.getCDAClass(umlClass);
// System.err.println("No Table For " + umlClass.getQualifiedName());
if (cdaClass != null) {
// if (transformerOptions.isIncludeTableView()) {
writer.println(
"<section audience=\"tableconformance\" conref=\"generated/_" + normalizedClassName +
".dita#classId/tableconformance\">");
writer.println("</section>");
// }
writer.println("<p> </p>"); // need a blank line before example code block
writer.println("<p><b>" + TransformAbstract.getPublicationName(umlClass) + " example</b></p>");
writer.println("<!-- TODO: insert custom instance example here -->");
writer.println("<!-- generated instance example follows -->");
writer.println("<codeblock conref=\"generated/_" + normalizedClassName + ".dita#classId/example\">");
writer.println("</codeblock>");
// writer.println("</fig>");
}
writer.println("</body>");
writer.println("</topic>");
}
private void appendHeader(PrintWriter writer, Class umlClass) {
String normalizedClassName = normalizeCodeName(umlClass.getName());
writer.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
writer.println("<!DOCTYPE topic PUBLIC \"-//OASIS//DTD DITA Topic//EN\" \"topic.dtd\">");
writer.println("<topic id=\"classId\" xml:lang=\"en-us\">");
writer.print("<title>");
writer.print(TransformAbstract.getPublicationName(umlClass));
writer.println("</title>");
writer.println(
"<shortdesc conref=\"generated/_" + normalizedClassName + ".dita#classId/shortdesc\"></shortdesc>");
writer.println("<prolog conref=\"generated/_" + normalizedClassName + ".dita#classId/prolog\"></prolog>");
}
private void addReference(Class source, NamedElement target) {
if (!UMLUtil.isSameProject(source, target) && !CDAModelUtil.isCDAModel(target)) {
IProject sourceProject = CDAModelUtil.getElementModelProject(source);
sourceProject = CDAModelUtil.getModelDocProject(sourceProject);
IProject targetProject = CDAModelUtil.getElementModelProject(target);
targetProject = CDAModelUtil.getModelDocProject(targetProject);
if (targetProject != null) {
IPath projectPath = new Path("/dita/classes/" + targetProject.getName());
IFolder referenceDitaFolder = sourceProject.getFolder(projectPath);
if (referenceDitaFolder.exists()) {
transformerOptions.addReference(
target.getQualifiedName(),
targetProject.getName() + "/classes/" + normalizeCodeName(target.getName()) + ".dita");
}
}
}
}
@Override
public Object caseClass(Class umlClass) {
String normalizedClassName = normalizeCodeName(umlClass.getName());
String pathFolder = "classes";
String fileName = normalizedClassName + ".dita";
IPath filePath = transformerOptions.getOutputPath().append(pathFolder).addTrailingSeparator().append(
normalizedClassName).addFileExtension("dita");
File file = filePath.toFile();
PrintWriter writer = null;
if (transformerOptions.isReset() && file.exists()) {
file.delete();
}
if (!file.exists()) {
try {
file.createNewFile();
writer = new PrintWriter(file);
appendHeader(writer, umlClass);
appendBody(writer, umlClass);
} catch (FileNotFoundException e) {
Logger.logException(e);
} catch (IOException e1) {
Logger.logException(e1);
} finally {
if (writer != null) {
writer.close();
}
}
}
List<String> packageContent = transformerOptions.getPackageContentList(umlClass.getNearestPackage());
packageContent.add(fileName);
checkClassReferences(umlClass, umlClass);
if (transformerOptions.isPrintTerminologyConstraintAsList()) {
CDACommonUtils.printTerminologyConstraintAsList(
umlClass, alreadyHandledForPrintTerminologyConstraintAsList);
}
Class cdaClass = CDAModelUtil.getCDAClass(umlClass);
if (cdaClass != null) {
if (CDAModelUtil.isClinicalDocument(cdaClass)) {
transformerOptions.getDocumentList().add(fileName);
} else if (CDAModelUtil.isSection(cdaClass)) {
transformerOptions.getSectionList().add(fileName);
} else if (CDAModelUtil.isClinicalStatement(cdaClass)) {
transformerOptions.getClinicalStatementList().add(fileName);
} else {
transformerOptions.getClassList().add(fileName);
}
} else {
// temporary workaround for QDM category section in pub, use section list
List<String> parentNames = UMLUtil.getAllParentNames(umlClass);
parentNames.remove(0);
if (parentNames.contains("QDM Element")) {
transformerOptions.getSectionList().add(fileName);
} else {
transformerOptions.getClassList().add(fileName);
}
}
return umlClass;
}
/**
* Checks recursively all classes associated to umlClass for inclusion in the Class References sections
*
* @param source
* a top level class of the main UML model (esp. not a participation class)
* @param umlClass
* @return <code>false</code> if umlClass is not required to be checked for inclusion in the Class References section, otherwise <code>true</code>
*/
private boolean checkClassReferences(Class source, Class umlClass) {
if (!alreadyHandled.add(umlClass)) {
return false;
}
if (CDAModelUtil.isCDAModel(umlClass) || CDAModelUtil.isDatatypeModel(umlClass)) {
return false;
}
// Loop over properties and generalizations - create references ditamap
for (Property property : umlClass.getOwnedAttributes()) {
if (property.getType() instanceof Class && checkClassReferences(source, (Class) property.getType()) &&
!CDAModelUtil.isDisplayInline(property)) {
addReference(source, property.getType());
}
}
for (Generalization generalization : umlClass.getGeneralizations()) {
if (generalization.getGeneral() instanceof Class &&
checkClassReferences(source, (Class) generalization.getGeneral())) {
addReference(source, generalization.getGeneral());
}
}
return true;
}
}