diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9f44aad --- /dev/null +++ b/.gitignore @@ -0,0 +1,47 @@ + +# runtime added files +build/ +lib/ + +# IntelliJ IDEA files +.idea/ +out/ +*.ipr +*.iws +*.iml + +# Eclipse files (and some general ones also used by Eclipse) +.metadata +.gradle +bin/ +tmp/ +*.tmp +*.bak +*.swp +*~.nib +local.properties +.settings/ +.loadpath + +# NetBeans files +nbproject/private/ +nbbuild/ +.nb-gradle/ +dist/ +nbdist/ +nbactions.xml +nb-configuration.xml + +# OSX auto files +.DS_Store +.AppleDouble +.LSOverride +._* + +# Windows auto files +Thumbs.db +ehthumbs.db +Desktop.ini + +# Linux auto files +*~ diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..93ce02d --- /dev/null +++ b/AUTHORS @@ -0,0 +1,60 @@ +Mantle Business Artifacts (http://github.com/moqui/mantle) + +This software is in the public domain under CC0 1.0 Universal plus a +Grant of Patent License. + +To the extent possible under law, the author(s) have dedicated all +copyright and related and neighboring rights to this software to the +public domain worldwide. This software is distributed without any +warranty. + +You should have received a copy of the CC0 Public Domain Dedication +along with this software (see the LICENSE.md file). If not, see +. + +=========================================================================== + +Copyright Waiver + +I dedicate any and all copyright interest in this software to the +public domain. I make this dedication for the benefit of the public at +large and to the detriment of my heirs and successors. I intend this +dedication to be an overt act of relinquishment in perpetuity of all +present and future rights to this software under copyright law. + +To the best of my knowledge and belief, my contributions are either +originally authored by me or are derived from prior works which I have +verified are also in the public domain and are not subject to claims +of copyright by other parties. + +To the best of my knowledge and belief, no individual, business, +organization, government, or other entity has any copyright interest +in my contributions, and I affirm that I will not make contributions +that are otherwise encumbered. + +Signed by git commit adding my legal name and git username: + +Written in 2010-2016 by David E. Jones - jonesde + +=========================================================================== + +Grant of Patent License + +I hereby grant to recipients of software a perpetual, worldwide, +non-exclusive, no-charge, royalty-free, irrevocable (except as stated in +this section) patent license to make, have made, use, offer to sell, sell, +import, and otherwise transfer the Work, where such license applies only to +those patent claims licensable by me that are necessarily infringed by my +Contribution(s) alone or by combination of my Contribution(s) with the +Work to which such Contribution(s) was submitted. If any entity institutes +patent litigation against me or any other entity (including a cross-claim +or counterclaim in a lawsuit) alleging that my Contribution, or the Work to +which I have contributed, constitutes direct or contributory patent +infringement, then any patent licenses granted to that entity under this +Agreement for that Contribution or Work shall terminate as of the date such +litigation is filed. + +Signed by git commit adding my legal name and git username: + +Written in 2010-2016 by David E. Jones - jonesde + diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..bb2c188 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,200 @@ +Because of a lack of patent licensing in CC0 1.0 this software includes a +separate Grant of Patent License adapted from Apache License 2.0. + +=========================================================================== + +Creative Commons Legal Code + +CC0 1.0 Universal + +CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE +LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN +ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS +INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES +REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS +PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM +THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED +HEREUNDER. + +Statement of Purpose + +The laws of most jurisdictions throughout the world automatically confer +exclusive Copyright and Related Rights (defined below) upon the creator +and subsequent owner(s) (each and all, an "owner") of an original work of +authorship and/or a database (each, a "Work"). + +Certain owners wish to permanently relinquish those rights to a Work for +the purpose of contributing to a commons of creative, cultural and +scientific works ("Commons") that the public can reliably and without fear +of later claims of infringement build upon, modify, incorporate in other +works, reuse and redistribute as freely as possible in any form whatsoever +and for any purposes, including without limitation commercial purposes. +These owners may contribute to the Commons to promote the ideal of a free +culture and the further production of creative, cultural and scientific +works, or to gain reputation or greater distribution for their Work in +part through the use and efforts of others. + +For these and/or other purposes and motivations, and without any +expectation of additional consideration or compensation, the person +associating CC0 with a Work (the "Affirmer"), to the extent that he or she +is an owner of Copyright and Related Rights in the Work, voluntarily +elects to apply CC0 to the Work and publicly distribute the Work under its +terms, with knowledge of his or her Copyright and Related Rights in the +Work and the meaning and intended legal effect of CC0 on those rights. + +1. Copyright and Related Rights. A Work made available under CC0 may be +protected by copyright and related or neighboring rights ("Copyright and +Related Rights"). Copyright and Related Rights include, but are not +limited to, the following: + + i. the right to reproduce, adapt, distribute, perform, display, + communicate, and translate a Work; + ii. moral rights retained by the original author(s) and/or performer(s); +iii. publicity and privacy rights pertaining to a person's image or + likeness depicted in a Work; + iv. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(a), below; + v. rights protecting the extraction, dissemination, use and reuse of data + in a Work; + vi. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation + thereof, including any amended or successor version of such + directive); and +vii. other similar, equivalent or corresponding rights throughout the + world based on applicable law or treaty, and any national + implementations thereof. + +2. Waiver. To the greatest extent permitted by, but not in contravention +of, applicable law, Affirmer hereby overtly, fully, permanently, +irrevocably and unconditionally waives, abandons, and surrenders all of +Affirmer's Copyright and Related Rights and associated claims and causes +of action, whether now known or unknown (including existing as well as +future claims and causes of action), in the Work (i) in all territories +worldwide, (ii) for the maximum duration provided by applicable law or +treaty (including future time extensions), (iii) in any current or future +medium and for any number of copies, and (iv) for any purpose whatsoever, +including without limitation commercial, advertising or promotional +purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each +member of the public at large and to the detriment of Affirmer's heirs and +successors, fully intending that such Waiver shall not be subject to +revocation, rescission, cancellation, termination, or any other legal or +equitable action to disrupt the quiet enjoyment of the Work by the public +as contemplated by Affirmer's express Statement of Purpose. + +3. Public License Fallback. Should any part of the Waiver for any reason +be judged legally invalid or ineffective under applicable law, then the +Waiver shall be preserved to the maximum extent permitted taking into +account Affirmer's express Statement of Purpose. In addition, to the +extent the Waiver is so judged Affirmer hereby grants to each affected +person a royalty-free, non transferable, non sublicensable, non exclusive, +irrevocable and unconditional license to exercise Affirmer's Copyright and +Related Rights in the Work (i) in all territories worldwide, (ii) for the +maximum duration provided by applicable law or treaty (including future +time extensions), (iii) in any current or future medium and for any number +of copies, and (iv) for any purpose whatsoever, including without +limitation commercial, advertising or promotional purposes (the +"License"). The License shall be deemed effective as of the date CC0 was +applied by Affirmer to the Work. Should any part of the License for any +reason be judged legally invalid or ineffective under applicable law, such +partial invalidity or ineffectiveness shall not invalidate the remainder +of the License, and in such case Affirmer hereby affirms that he or she +will not (i) exercise any of his or her remaining Copyright and Related +Rights in the Work or (ii) assert any associated claims and causes of +action with respect to the Work, in either case contrary to Affirmer's +express Statement of Purpose. + +4. Limitations and Disclaimers. + + a. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + b. Affirmer offers the Work as-is and makes no representations or + warranties of any kind concerning the Work, express, implied, + statutory or otherwise, including without limitation warranties of + title, merchantability, fitness for a particular purpose, non + infringement, or the absence of latent or other defects, accuracy, or + the present or absence of errors, whether or not discoverable, all to + the greatest extent permissible under applicable law. + c. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without + limitation any person's Copyright and Related Rights in the Work. + Further, Affirmer disclaims responsibility for obtaining any necessary + consents, permissions or other rights required for any use of the + Work. + d. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to + this CC0 or use of the Work. + + +=========================================================================== + +Grant of Patent License + +"License" shall mean the terms and conditions for use, reproduction, and +distribution. + +"Licensor" shall mean the original copyright owner or entity authorized by +the original copyright owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other +entities that control, are controlled by, or are under common control with +that entity. For the purposes of this definition, "control" means (i) the +power, direct or indirect, to cause the direction or management of such +entity, whether by contract or otherwise, or (ii) ownership of fifty +percent (50%) or more of the outstanding shares, or (iii) beneficial +ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising +permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, +including but not limited to software source code, documentation source, +and configuration files. + +"Object" form shall mean any form resulting from mechanical transformation +or translation of a Source form, including but not limited to compiled +object code, generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, +made available under the License, as indicated by a copyright notice that +is included in or attached to the work. + +"Derivative Works" shall mean any work, whether in Source or Object form, +that is based on (or derived from) the Work and for which the editorial +revisions, annotations, elaborations, or other modifications represent, as +a whole, an original work of authorship. For the purposes of this License, +Derivative Works shall not include works that remain separable from, or +merely link (or bind by name) to the interfaces of, the Work and +Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original +version of the Work and any modifications or additions to that Work or +Derivative Works thereof, that is intentionally submitted to Licensor for +inclusion in the Work by the copyright owner or by an individual or Legal +Entity authorized to submit on behalf of the copyright owner. For the +purposes of this definition, "submitted" means any form of electronic, +verbal, or written communication sent to the Licensor or its +representatives, including but not limited to communication on electronic +mailing lists, source code control systems, and issue tracking systems that +are managed by, or on behalf of, the Licensor for the purpose of discussing +and improving the Work, but excluding communication that is conspicuously +marked or otherwise designated in writing by the copyright owner as "Not a +Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on +behalf of whom a Contribution has been received by Licensor and +subsequently incorporated within the Work. + +Each Contributor hereby grants to You a perpetual, worldwide, +non-exclusive, no-charge, royalty-free, irrevocable (except as stated in +this section) patent license to make, have made, use, offer to sell, sell, +import, and otherwise transfer the Work, where such license applies only to +those patent claims licensable by such Contributor that are necessarily +infringed by their Contribution(s) alone or by combination of their +Contribution(s) with the Work to which such Contribution(s) was submitted. +If You institute patent litigation against any entity (including a +cross-claim or counterclaim in a lawsuit) alleging that the Work or a +Contribution incorporated within the Work constitutes direct or +contributory patent infringement, then any patent licenses granted to You +under this License for that Work shall terminate as of the date such +litigation is filed. diff --git a/MoquiConf.xml b/MoquiConf.xml new file mode 100644 index 0000000..fd6d6f9 --- /dev/null +++ b/MoquiConf.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/README.md b/README.md index f31f0f8..c84b45a 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,15 @@ -# moqui-wikitext -Moqui tool component for Eclipse Mylyn Wikitext to render wiki files such as confluence, mediawiki, textile, tracwiki, twiki +# Moqui Eclipse Mylyn WikiText Tool Component + +[![license](http://img.shields.io/badge/license-CC0%201.0%20Universal-blue.svg)](https://github.com/moqui/moqui-wikitext/blob/master/LICENSE.md) +[![release](http://img.shields.io/github/release/moqui/moqui-wikitext.svg)](https://github.com/moqui/moqui-wikitext/releases) + +Moqui tool component for Eclipse Mylyn Wikitext to render wiki files such as confluence, mediawiki, textile, tracwiki, and twiki. + +To install run (with moqui-framework): + + $ ./gradlew getComponent -Pcomponent=moqui-wikitext + +This will add the component to the Moqui runtime/component directory. + +To use just install this component. The configuration for the TemplateRenderer implementations is already in place in the +MoquiConf.xml included in this component and will be merged with the main configuration at runtime. diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..58092e7 --- /dev/null +++ b/build.gradle @@ -0,0 +1,66 @@ +/* + * This software is in the public domain under CC0 1.0 Universal plus a + * Grant of Patent License. + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to the + * public domain worldwide. This software is distributed without any + * warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software (see the LICENSE.md file). If not, see + * . + */ + +apply plugin: 'groovy' + +sourceCompatibility = '1.7' +version = '1.0.0' +def jarBaseName = 'moqui-wikitext' +def moquiDir = projectDir.parentFile.parentFile.parentFile +def frameworkDir = file(moquiDir.absolutePath + '/framework') + +// to run use "gradle dependencyUpdates" +apply plugin: 'com.github.ben-manes.versions' +buildscript { + repositories { jcenter() } + dependencies { classpath 'com.github.ben-manes:gradle-versions-plugin:0.12.0' } +} +dependencyUpdates.resolutionStrategy = { componentSelection { rules -> rules.all { ComponentSelection selection -> + boolean rejected = ['alpha', 'beta', 'rc', 'cr', 'm'].any { qualifier -> selection.candidate.version ==~ /(?i).*[.-]${qualifier}[.\d-]*/ } + if (rejected) selection.reject('Release candidate') +} } } + +repositories { + flatDir name: 'localLib', dirs: frameworkDir.absolutePath + '/lib' + flatDir name: 'librepo', dirs: projectDir.absolutePath + '/librepo' + jcenter() +} + +dependencies { + compile project(':framework') + + // Mylyn Wikitext: only older versions found in jcenter or mvnrepository + compile name: 'org.eclipse.mylyn.wikitext.core_1.8.0.I20121130-0624', version: '' // EPL + compile name: 'org.eclipse.mylyn.wikitext.confluence.core_1.8.0.I20121130-0624', version: '' // EPL + compile name: 'org.eclipse.mylyn.wikitext.mediawiki.core_1.8.0.I20121130-0624', version: '' // EPL + compile name: 'org.eclipse.mylyn.wikitext.textile.core_1.8.0.I20121130-0624', version: '' // EPL + compile name: 'org.eclipse.mylyn.wikitext.tracwiki.core_1.8.0.I20121130-0624', version: '' // EPL + compile name: 'org.eclipse.mylyn.wikitext.twiki.core_1.8.0.I20121130-0624', version: '' // EPL +} + +// by default the Java plugin runs test on build, change to not do that (only run test if explicit task) +check.dependsOn.remove(test) +task cleanLib(type: Delete) { delete fileTree(dir: projectDir.absolutePath+'/lib', include: '*') } +clean.dependsOn cleanLib + +jar { + destinationDir = file(projectDir.absolutePath + '/lib') + baseName = jarBaseName +} +task copyDependencies << { + copy { from (configurations.runtime - project(':framework').configurations.runtime - project(':framework').jar.archivePath) + into file(projectDir.absolutePath + '/lib') } +} +copyDependencies.dependsOn cleanLib +jar.dependsOn copyDependencies diff --git a/librepo/org.eclipse.mylyn.wikitext.confluence.core_1.8.0.I20121130-0624.jar b/librepo/org.eclipse.mylyn.wikitext.confluence.core_1.8.0.I20121130-0624.jar new file mode 100644 index 0000000..337a042 Binary files /dev/null and b/librepo/org.eclipse.mylyn.wikitext.confluence.core_1.8.0.I20121130-0624.jar differ diff --git a/librepo/org.eclipse.mylyn.wikitext.core_1.8.0.I20121130-0624.jar b/librepo/org.eclipse.mylyn.wikitext.core_1.8.0.I20121130-0624.jar new file mode 100644 index 0000000..d564aa1 Binary files /dev/null and b/librepo/org.eclipse.mylyn.wikitext.core_1.8.0.I20121130-0624.jar differ diff --git a/librepo/org.eclipse.mylyn.wikitext.mediawiki.core_1.8.0.I20121130-0624.jar b/librepo/org.eclipse.mylyn.wikitext.mediawiki.core_1.8.0.I20121130-0624.jar new file mode 100644 index 0000000..9e7d177 Binary files /dev/null and b/librepo/org.eclipse.mylyn.wikitext.mediawiki.core_1.8.0.I20121130-0624.jar differ diff --git a/librepo/org.eclipse.mylyn.wikitext.textile.core_1.8.0.I20121130-0624.jar b/librepo/org.eclipse.mylyn.wikitext.textile.core_1.8.0.I20121130-0624.jar new file mode 100644 index 0000000..7723432 Binary files /dev/null and b/librepo/org.eclipse.mylyn.wikitext.textile.core_1.8.0.I20121130-0624.jar differ diff --git a/librepo/org.eclipse.mylyn.wikitext.tracwiki.core_1.8.0.I20121130-0624.jar b/librepo/org.eclipse.mylyn.wikitext.tracwiki.core_1.8.0.I20121130-0624.jar new file mode 100644 index 0000000..5b9d7e4 Binary files /dev/null and b/librepo/org.eclipse.mylyn.wikitext.tracwiki.core_1.8.0.I20121130-0624.jar differ diff --git a/librepo/org.eclipse.mylyn.wikitext.twiki.core_1.8.0.I20121130-0624.jar b/librepo/org.eclipse.mylyn.wikitext.twiki.core_1.8.0.I20121130-0624.jar new file mode 100644 index 0000000..ee885ed Binary files /dev/null and b/librepo/org.eclipse.mylyn.wikitext.twiki.core_1.8.0.I20121130-0624.jar differ diff --git a/src/main/groovy/org/moqui/wikitext/FtlCwikiTemplateRenderer.groovy b/src/main/groovy/org/moqui/wikitext/FtlCwikiTemplateRenderer.groovy new file mode 100644 index 0000000..fa80c4c --- /dev/null +++ b/src/main/groovy/org/moqui/wikitext/FtlCwikiTemplateRenderer.groovy @@ -0,0 +1,98 @@ +/* + * This software is in the public domain under CC0 1.0 Universal plus a + * Grant of Patent License. + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to the + * public domain worldwide. This software is distributed without any + * warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software (see the LICENSE.md file). If not, see + * . + */ +package org.moqui.wikitext + +import groovy.transform.CompileStatic +import org.eclipse.mylyn.wikitext.confluence.core.ConfluenceLanguage +import org.eclipse.mylyn.wikitext.core.parser.MarkupParser +import org.eclipse.mylyn.wikitext.core.parser.builder.HtmlDocumentBuilder +import org.moqui.context.ResourceReference +import org.moqui.context.TemplateRenderer +import org.moqui.impl.screen.ScreenRenderImpl +import org.moqui.jcache.MCache +import org.slf4j.Logger +import org.slf4j.LoggerFactory +import freemarker.template.Template +import org.moqui.impl.context.ExecutionContextFactoryImpl +import org.moqui.context.ExecutionContextFactory + +import javax.cache.Cache + +@CompileStatic +class FtlCwikiTemplateRenderer implements TemplateRenderer { + protected final static Logger logger = LoggerFactory.getLogger(FtlCwikiTemplateRenderer.class) + + protected ExecutionContextFactoryImpl ecfi + + protected Cache templateFtlLocationCache + + FtlCwikiTemplateRenderer() { } + + TemplateRenderer init(ExecutionContextFactory ecf) { + this.ecfi = (ExecutionContextFactoryImpl) ecf + this.templateFtlLocationCache = ecfi.cacheFacade.getCache("resource.ftl.location", String.class, Template.class) + return this + } + + void render(String location, Writer writer) { + Template theTemplate; + if (templateFtlLocationCache instanceof MCache) { + MCache mCache = (MCache) templateFtlLocationCache; + ResourceReference rr = ecfi.getResourceFacade().getLocationReference(location); + long lastModified = rr != null ? rr.getLastModified() : 0L; + theTemplate = mCache.get(location, lastModified); + } else { + // TODO: doesn't support on the fly reloading without cache expire/clear! + theTemplate = templateFtlLocationCache.get(location); + } + if (theTemplate == null) theTemplate = makeTemplate(location) + if (theTemplate == null) throw new IllegalArgumentException("Could not find template at ${location}") + theTemplate.createProcessingEnvironment(ecfi.executionContext.context, writer).process() + } + + protected Template makeTemplate(String location) { + Template theTemplate = (Template) templateFtlLocationCache.get(location) + if (theTemplate != null) return theTemplate + + Template newTemplate + try { + StringWriter cwikiWriter = new StringWriter() + HtmlDocumentBuilder builder = new HtmlDocumentBuilder(cwikiWriter) + // avoid the and tags + builder.setEmitAsDocument(false) + // if we're in the context of a screen render, use it's URL for the base + ScreenRenderImpl sri = (ScreenRenderImpl) ecfi.getEci().getContext().getByString("sri") + if (sri != null) builder.setBase(sri.getBaseLinkUri()) + + MarkupParser parser = new MarkupParser(new ConfluenceLanguage()) + parser.setBuilder(builder) + parser.parse(ecfi.resourceFacade.getLocationText(location, false)) + + Reader templateReader = new StringReader(cwikiWriter.toString()) + newTemplate = new Template(location, templateReader, ecfi.resourceFacade.ftlTemplateRenderer.getFtlConfiguration()) + } catch (Exception e) { + throw new IllegalArgumentException("Error while initializing template at [${location}]", e) + } + + if (newTemplate) templateFtlLocationCache.put(location, newTemplate) + return newTemplate + } + + String stripTemplateExtension(String fileName) { + String stripped = fileName.contains(".cwiki") ? fileName.replace(".cwiki", "") : fileName + return stripped.contains(".ftl") ? stripped.replace(".ftl", "") : stripped + } + + void destroy() { } +} diff --git a/src/main/groovy/org/moqui/wikitext/WikiTemplateRenderer.groovy b/src/main/groovy/org/moqui/wikitext/WikiTemplateRenderer.groovy new file mode 100644 index 0000000..bc9d9e0 --- /dev/null +++ b/src/main/groovy/org/moqui/wikitext/WikiTemplateRenderer.groovy @@ -0,0 +1,110 @@ +/* + * This software is in the public domain under CC0 1.0 Universal plus a + * Grant of Patent License. + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to the + * public domain worldwide. This software is distributed without any + * warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software (see the LICENSE.md file). If not, see + * . + */ +package org.moqui.wikitext + +import org.eclipse.mylyn.wikitext.confluence.core.ConfluenceLanguage +import org.eclipse.mylyn.wikitext.core.parser.MarkupParser +import org.eclipse.mylyn.wikitext.core.parser.builder.HtmlDocumentBuilder +import org.eclipse.mylyn.wikitext.mediawiki.core.MediaWikiLanguage +import org.eclipse.mylyn.wikitext.textile.core.TextileLanguage +import org.eclipse.mylyn.wikitext.tracwiki.core.TracWikiLanguage +import org.eclipse.mylyn.wikitext.twiki.core.TWikiLanguage + +import org.moqui.BaseException +import org.moqui.context.ExecutionContextFactory +import org.moqui.context.ResourceReference +import org.moqui.context.TemplateRenderer +import org.moqui.impl.context.ExecutionContextFactoryImpl +import org.moqui.impl.screen.ScreenRenderImpl +import org.moqui.jcache.MCache +import org.slf4j.Logger +import org.slf4j.LoggerFactory + +import javax.cache.Cache + +class WikiTemplateRenderer implements TemplateRenderer { + protected final static Logger logger = LoggerFactory.getLogger(WikiTemplateRenderer.class) + + protected ExecutionContextFactoryImpl ecfi + protected Cache templateWikiLocationCache + + WikiTemplateRenderer() { } + + TemplateRenderer init(ExecutionContextFactory ecf) { + this.ecfi = (ExecutionContextFactoryImpl) ecf + this.templateWikiLocationCache = ecfi.cacheFacade.getCache("resource.wiki.location", String.class, String.class) + return this + } + + void render(String location, Writer writer) { + String wikiText; + if (templateWikiLocationCache instanceof MCache) { + MCache mCache = (MCache) templateWikiLocationCache; + ResourceReference rr = ecfi.getResourceFacade().getLocationReference(location); + long lastModified = rr != null ? rr.getLastModified() : 0L; + wikiText = mCache.get(location, lastModified); + } else { + // TODO: doesn't support on the fly reloading without cache expire/clear! + wikiText = templateWikiLocationCache.get(location); + } + + if (wikiText) { + writer.write(wikiText) + return + } + + String sourceText = ecfi.resourceFacade.getLocationText(location, false) + if (!sourceText) { + logger.warn("In wiki template render got no text from location ${location}") + return + } + + StringWriter localWriter = new StringWriter() + HtmlDocumentBuilder builder = new HtmlDocumentBuilder(localWriter) + // avoid the and tags + builder.setEmitAsDocument(false) + // if we're in the context of a screen render, use it's URL for the base + ScreenRenderImpl sri = (ScreenRenderImpl) ecfi.getEci().getContext().getByString("sri") + if (sri != null) builder.setBase(sri.getBaseLinkUri()) + + MarkupParser parser + if (location.endsWith(".cwiki") || location.endsWith(".confluence")) parser = new MarkupParser(new ConfluenceLanguage()) + else if (location.endsWith(".mediawiki")) parser = new MarkupParser(new MediaWikiLanguage()) + else if (location.endsWith(".textile")) parser = new MarkupParser(new TextileLanguage()) + else if (location.endsWith(".tracwiki")) parser = new MarkupParser(new TracWikiLanguage()) + else if (location.endsWith(".twiki")) parser = new MarkupParser(new TWikiLanguage()) + else throw new BaseException("Extension not supported for wiki rendering for location ${location}") + + parser.setBuilder(builder) + parser.parse(sourceText) + + wikiText = localWriter.toString() + if (wikiText) { + templateWikiLocationCache.put(location, wikiText) + writer.write(wikiText) + } + } + + String stripTemplateExtension(String fileName) { + if (fileName.contains(".cwiki")) return fileName.replace(".cwiki", "") + else if (fileName.contains(".confluence")) return fileName.replace(".confluence", "") + else if (fileName.contains(".mediawiki")) return fileName.replace(".mediawiki", "") + else if (fileName.contains(".textile")) return fileName.replace(".textile", "") + else if (fileName.contains(".tracwiki")) return fileName.replace(".tracwiki", "") + else if (fileName.contains(".twiki")) return fileName.replace(".twiki", "") + else return fileName + } + + void destroy() { } +}