… this comes of course before applying all the templates via code in statements after this. Good to have -> would be good if this auto updates as well when rendering.
Apply a base word doc template ( how to specify the path to this i.e. from the ones we have in Doc Composer -> Manage Templates ), so that it can include all styling and cover page from that base word doc template. The following didn’t apply to the IReportDiagramDetails.
Write revision history ( of ArchiMate Diagram ) either via the Open API code or via the XML template that I can include via Open API as a IRDOOTemplate
Pass a value from Open API Code to inside a XML Template ( applied by IRDOOTemplate )
Pass a value from Open API Code to Word Doc Base Template e.g. ${TEXT, ”departmentName”} in word doc base template
Write version of Doc Composer - Doc Template and XML Templates
Specify page orientation for each IRDOOTemplate or in general - Portrait/ Landscape
IReportDiagramDetails documentDetails = ...;
documentDetails.getReportDiagramOption().setWordDocumnentTemplatePath(...); // fyi: sorry for typo on this function name: documnent
documentDetails.getReportDiagramOption().setUseWordDocumnentTemplate(true);
fyi: setDocBasePath(…) is used for Fill-in document
Sorry, may I ask you a question first.
When I read your question 5, the ${TEXT, ...} is used in Fill-in Doc.
As screenshot, are you using Fill-in Doc?
2.
Sorry, may I ask you a question first.
When I read your question 5 , the ${TEXT, ...} is used in Fill-in Doc.
LN: I am using Fill In Doc that I want to apply as a DocBasePath - how do i specify its path ( don’t want to specify a local path but VP Path - I can pick up from workspace location I guess - ApplicationManager.instance().getWorkspaceLocation() ) & how do i pass the value of departmentName from Open API based on users input
3.
Sorry, the content of the revision history comes from where?
LN: ArchiMate Projects commit history
6.
Sorry, what is ‘version’ of Doc Composer? (similar to question 3?)
LN: The version of the word doc base template applied via DocBasePath
Sorry about that, we didn’t aware user may create a blank new document via OpenAPI. We need to spend some time on enhance it.
At this moment, I may provide a simple sample to answer the Q2, Q5 first.
sample DocBase: MyDocBase.docx (252.9 KB)
String lDocBasePath = ...;//"MyDocBase.docx";
File lOutput = ...;
DiagramManager lDiagramManager = ApplicationManager.instance().getDiagramManager();
IProject lProject = ApplicationManager.instance().getProjectManager().getProject();
IReportDiagramDetailsContainer lDocDetailsContainer;
{
IModelElement[] lElements = lProject.toAllLevelModelElementArray(IModelElementFactory.MODEL_TYPE_REPORT_DIAGRAM_DETAILS_CONTAINER);
if (lElements == null || lElements.length == 0) {
lDocDetailsContainer = IModelElementFactory.instance().createReportDiagramDetailsContainer();
}
else {
lDocDetailsContainer = (IReportDiagramDetailsContainer) lElements[0];
}
}
IReportDiagramUIModel lDocument = (IReportDiagramUIModel) lDiagramManager.createDiagram(IDiagramTypeConstants.DIAGRAM_TYPE_REPORT_DIAGRAM);
IReportDiagramDetails lDocDetails = lDocDetailsContainer.createReportDiagramDetails();
lDocument.setGenericXMLElementAddress(lDocDetails.getAddress());
// Q2. set it is Fill-In Doc, and DocBasePath.
lDocDetails.setFillInDoc(true);
lDocDetails.setDocBasePath(lDocBasePath);
/*
* Sorry, this .version is internal used (we didn't aware user will create a blank new IReportDiagramUIModel via OpenAPI)
* Please hardcode the follow "20150413" and don't modify it.
*/
lDocDetails.setVersion("20150413");
// Q5. specify ${TEXT, ...} value.
// my doc base defined a "Text-1" ${TEXT, Text-1}
IFIText lText = lDocDetails.getFITextByName("Text-1");
if (lText == null) {
lText = lDocDetails.createFIText();
lText.setName("Text-1");
lDocDetails.addFiField(lText);
/*
* the IFIText is referenced by ReportDiagramDetails in both .children + .fiFields properties
* .getFITextByName(...) & .createFIText(...) working on .children property
* .addFiField(...) working on .fiFields property
*/
}
IFITextInstance lTextInstance; // the value of ${TEXT, ...} is specified in TextInstance, on this case, this ${TEXT, ...} should have 1 instance only.
if (lText.instanceCount() == 0) {
lTextInstance = IModelElementFactory.instance().createFITextInstance();
lText.addInstance(lTextInstance);
}
else {
lTextInstance = lText.getInstanceByIndex(0);
}
lTextInstance.setNickDescription("Hello World");
lTextInstance.setNickHTMLDescription("<html><body>Hello World</body></html>");
lDiagramManager.openDiagram(lDocument);
// TODO
/*
* Sorry, this function is only available to generate word document for Non Fill-In Doc.
* We will enhance to support generating Fill-In Doc. Please wait.
*/
ApplicationManager.instance().getDocumentationManager().generateDocComposerWord(lDocument, lOutput, null);
On the above sample code, a Fill-In Doc can be created with “Hello World” text specified.
You can generate the .docx via Fill-In Doc’s Generate/Preview button
But cannot generate via OpenAPI’s DocumentManager.generateDocComposerWord(...) function.
We will post here if the enhancement is ready. Please wait…
It would be great to have a feature that supports passing variable values gathered from end user via a dialog for example and then added to the cover page/ document information page - using Open API’s DocumentManager.generateDocComposerWord(…) function.That would be extremely useful for us.
String lDocBasePath = ...;//"MyDocBase.docx";
File lOutput = ...;
DiagramManager lDiagramManager = ApplicationManager.instance().getDiagramManager();
DocumentationManager lDocManager = ApplicationManager.instance().getDocumentationManager();
IProject lProject = ApplicationManager.instance().getProjectManager().getProject();
// on this demo, assume the Project has a "Transition Architectures" archimate diagram. This ArchiMate diagram will be generated into document.
IArchiMateDiagramUIModel lArchiMateDiagram = null; // assume not null
for (IDiagramUIModel lDiagram : lProject.toDiagramArray()) {
if (lDiagram instanceof IArchiMateDiagramUIModel && "Transition Architectures".equals(lDiagram.getName())) {
lArchiMateDiagram = (IArchiMateDiagramUIModel) lDiagram;
}
}
IReportDiagramDetailsContainer lDocDetailsContainer;
{
IModelElement[] lElements = lProject.toAllLevelModelElementArray(IModelElementFactory.MODEL_TYPE_REPORT_DIAGRAM_DETAILS_CONTAINER);
if (lElements == null || lElements.length == 0) {
lDocDetailsContainer = IModelElementFactory.instance().createReportDiagramDetailsContainer();
}
else {
lDocDetailsContainer = (IReportDiagramDetailsContainer) lElements[0];
}
}
IReportDiagramUIModel lDocument = (IReportDiagramUIModel) lDiagramManager.createDiagram(IDiagramTypeConstants.DIAGRAM_TYPE_REPORT_DIAGRAM);
IReportDiagramDetails lDocDetails = lDocDetailsContainer.createReportDiagramDetails();
lDocument.setGenericXMLElementAddress(lDocDetails.getAddress());
// Q2. set it is Fill-In Doc, and DocBasePath.
lDocDetails.setFillInDoc(true);
lDocDetails.setDocBasePath(lDocBasePath);
/*
* Sorry, this .version is internal used (we didn't aware user will create a blank new IReportDiagramUIModel via OpenAPI)
* Please hardcode the follow "20150413" and don't modify it.
*/
lDocDetails.setVersion("20150413");
if (lDocDetails.rDNumberingSettingCount() == 0) {
lDocDetails.createRDNumberingSetting();
}
lDocManager.initDefaultRDNumberingSetting(lDocDetails.getRDNumberingSettingByIndex(0));
if (lDocDetails.rDStyleRepositoryCount() == 0) {
lDocDetails.createRDStyleRepository();
}
lDocManager.initDefaultRDStyleRepository(lDocDetails.getRDStyleRepositoryByIndex(0));
// Q6. Commit History of this document
{
/*
* ${PROJECT, Document Revisions}
*
* "Document Revisions" is my customized TemplateXML
*/
IRDTemplateVariable lRevDiffScopeVar = IModelElementFactory.instance().createRDTemplateVariable();
lRevDiffScopeVar.setName("${Doc.RevDiff.scope}"); // this name was specified in TemplateXML
lRevDiffScopeVar.setKind(IRDTemplateVariable.KIND_REV_DIFF_SCOPE);
IRDRevDiffScope lRevDiffScope = IModelElementFactory.instance().createRDRevDiffScope();
lRevDiffScopeVar.setRevDiffScope(lRevDiffScope);
lRevDiffScope.setBranchName("trunk");
lRevDiffScope.setFromRev(1);
lDocDetails.addVariable(lRevDiffScopeVar);
}
// Q5. specify ${TEXT, ...} value.
{
// ${TEXT, Text-1}
IFIText lText = lDocDetails.getFITextByName("Text-1");
if (lText == null) {
lText = lDocDetails.createFIText();
lText.setName("Text-1");
lDocDetails.addFiField(lText);
/*
* the IFIText is referenced by ReportDiagramDetails in both .children + .fiFields properties
* .getFITextByName(...) & .createFIText(...) working on .children property
* .addFiField(...) working on .fiFields property
*/
}
IFITextInstance lTextInstance; // the value of ${TEXT, ...} is specified in TextInstance, on this case, this ${TEXT, ...} should have 1 instance only.
if (lText.instanceCount() == 0) {
lTextInstance = IModelElementFactory.instance().createFITextInstance();
lText.addInstance(lTextInstance);
}
else {
lTextInstance = lText.getInstanceByIndex(0);
}
lTextInstance.setNickDescription("Hello World");
lTextInstance.setNickHTMLDescription("<html><body>Hello World</body></html>");
}
{
// ${DIAGRAM, Main ArchiMate, ArchiMateDiagram, One, My TemplateXML with Variable}
IFIDiagram lMainArchiMate = lDocDetails.getFIDiagramByName("Main ArchiMate");
if (lMainArchiMate == null) {
lMainArchiMate = lDocDetails.createFIDiagram();
lMainArchiMate.setName("Main ArchiMate");
lDocDetails.addFiField(lMainArchiMate);
}
/*
* if "One" or "Any" is specified, specify the .selectedDiagramAddresses
* else if "LoopInElement" is specified, specify the .selectedLoopInElement
*/
//
lMainArchiMate.setSelectedDiagramAddresses(new String[] {lArchiMateDiagram.getId()});
// Q4. specify variable for the IRDOOTemplate.
{
/*
* in Fill-in Doc, there is no instance of IRDOOTemplate; The variables can be specified in
* If the TemplateXML is generated for ${DIAGRAM, ...}, or ${ELEMENT, ...}
* the variable can be specified in IFIDiagram, or IFIElement
*/
IRDTemplateVariable lLookupModelTypeVar = IModelElementFactory.instance().createRDTemplateVariable();
lLookupModelTypeVar.setName("${lookupModelType}");
lLookupModelTypeVar.setKind(IRDTemplateVariable.KIND_NORMAL);
lLookupModelTypeVar.setFollowGlobal(false);
lLookupModelTypeVar.setValue(IModelElementFactory.MODEL_TYPE_ARCHI_MATE_GAP);
lMainArchiMate.addVariable(lLookupModelTypeVar);
}
// Q3. Commit History of the ArchiMate diagram
{
/*
* "Revision Differences" is a predefined TemplateXML, use <RevDiff scope=${...}> used to generate the 'changes' in your revisions.
* <RevDiff> .scope is a variable, allows you to specify the scope of the changes.
* On the following case, I will show my "Transition Architectures" archimate diagram's changes from revision '3' to current revision.
*/
IRDTemplateVariable lRevDiffScopeVar = IModelElementFactory.instance().createRDTemplateVariable();
lRevDiffScopeVar.setName("${Diagram.RevDiff.scope}"); // this name was specified in TemplateXML
lRevDiffScopeVar.setKind(IRDTemplateVariable.KIND_REV_DIFF_SCOPE);
lRevDiffScopeVar.setFollowGlobal(false);
IRDRevDiffScope lRevDiffScope = IModelElementFactory.instance().createRDRevDiffScope();
lRevDiffScopeVar.setRevDiffScope(lRevDiffScope);
lRevDiffScope.setBranchName("trunk");
lRevDiffScope.setFromRev(3);
lRevDiffScope.setScopeType(IRDRevDiffScope.SCOPE_TYPE_DIAGRAM);
lRevDiffScope.setScopeDiagramIds(new String[] {lArchiMateDiagram.getId()});
lMainArchiMate.addVariable(lRevDiffScopeVar);
}
}
// lDiagramManager.openDiagram(lDocument);
lDocManager.generateDocComposerWord(lDocument, lOutput, null);
Q2. Specify DocBase after created IReportDiagramDetails
// Q2. set it is Fill-In Doc, and DocBasePath.
lDocDetails.setFillInDoc(true);
lDocDetails.setDocBasePath(lDocBasePath);
Q7. Portrait/Landscape
It is handled by sections.
Fill-in Doc does not support insert section via TemplateXML. It is expected to be predefined in your DocBase.
For example, in my DocBase, at the end of 2nd page, specified a Section-Break to let 3rd page can be set to Landscape.
And end of the 3rd page, specified another Section-Break to let 4th page set back to Portrait.
Q6. The version of the word doc base template applied via DocBasePath
Sorry, I am still not understand. On above sample code, I wrongly show you how to list the commit history of your project. as following screenshot.
Query 1: The value of REVIEWER_NAME which I am trying to get in my base word template document “C:\\MyFolder\MyBaseDoc.docx” by using ${TEXT, REVIEWER_NAME} is not being received ( rendered ) in the word document.
Query 2: If I set the
reportDiagramDetails.setFillInDoc(true);
the document is not generated by the following line
ApplicationManager.instance().getDocumentationManager().generateDocComposerWord(reportDiagramUIModel, new File(“C:\MyFolder\MyGeneratedDocument.docx”), null);
It just outputs the base doc template MyBaseDoc.docx and does not render the DCTL XML template sections but the variable values are getting properly replaced now for ${TEXT, REVIEWER_NAME}
Query 3: Instead of passing the local path here, can i upload this base word doc template to Doc Composer and specify the path in VP itself instead of “C:\\MyFolder\MyBaseDoc.docx” local path
reportDiagramOption.setWordDocumnentTemplatePath( “C:\MyFolder\MyBaseDoc.docx” );
At a high level , I am trying to do the following
use a base word doc template ( which has all my styles and cover page only - so that it uses styles from here for generated document )
render the rest of the document using existing template DCTL xml code by creating IRDOOTemplate and adding them to IReportDiagramDetailsContainer using the Java Open API code.
Pass some of the values for cover page using a Dialog in Open API and then creating IFIText variables as above
I cannot comment the code you commented because that is the code that renders all the rest of the sections in my document. Let me explain please.
To Simplify this, the use case is as below
Use Base Word Doc template that already is uploaded to Doc Composer Tools > Doc Composer > Manage Doc Templates > New - and then upload. It serves the purpose of providing a) Styles b) 1st Page i.e. Cover Page c) 2nd Page i.e. Document Information Page ( so I don’t want to do all this via Open API )
The 2nd page i.e. the Document Information Page of my generated document should contain information collected by Open API dialog from end user and passed to word doc ${TEXT, REVIEWER_NAME} as a example
Page 3 onwards of my generated document should render all following sections dynamically based on conditions
a) Apply templates dynamically based on condition using Open API - Note: templates are chosen based on conditions of user input ( Open API Dialog )
`ApplicationManager.instance().getDocumentationManager().generateDocComposerWord(reportDiagramUIModel, new File(docName), null);`
Open it directly automatically in front of user - something like
ApplicationManager.instance().getViewManager().showMessage("Generated at path: "+docName);
if (Desktop.isDesktopSupported()) {
Desktop.getDesktop().open(new File(docName));
}
Since you are using Fill-in Doc, the section-break should be predefined in your DocBase .docx,
and your DocBase .docx should contains all your ${TEXT, …}, ${DIAGRAM, …}, etc… for generating the content based on your DocBase.