From d9e838bc53e6440a6631c604c975b03e27c64a4c Mon Sep 17 00:00:00 2001 From: Boubaker Khanfir Date: Fri, 15 Nov 2024 19:40:44 +0100 Subject: [PATCH] feat: Move JCR Services from Meeds - Meeds-io/meeds#2537 (#332) --- exo.jcr.component.core/pom.xml | 6 +- .../services/jdbc/DataSourceProvider.java | 56 + .../jdbc/impl/DataSourceProviderImpl.java | 182 ++ .../services/jdbc/impl/ManagedConnection.java | 574 ++++++ .../services/jdbc/impl/ManagedDataSource.java | 182 ++ .../services/rpc/RPCException.java | 44 + .../exoplatform/services/rpc/RPCService.java | 150 ++ .../services/rpc/RemoteCommand.java | 45 + .../services/rpc/SingleMethodCallCommand.java | 147 ++ .../services/rpc/TopologyChangeEvent.java | 70 + .../services/rpc/TopologyChangeListener.java | 38 + .../services/rpc/impl/AbstractRPCService.java | 982 ++++++++++ .../services/rpc/jgv3/RPCServiceImpl.java | 120 ++ .../transaction/ActionNonTxAware.java | 127 ++ exo.jcr.component.ext/pom.xml | 3 - .../rest/ext/groovy/BaseResourceId.java | 73 + .../rest/ext/groovy/ClassPathEntry.java | 40 + .../groovy/DefaultGroovyResourceLoader.java | 193 ++ .../ext/groovy/ExtendedGroovyClassLoader.java | 300 +++ .../ext/groovy/GroovyClassLoaderProvider.java | 82 + .../rest/ext/groovy/GroovyJaxrsPublisher.java | 681 +++++++ .../ext/groovy/MalformedScriptException.java | 38 + .../services/rest/ext/groovy/ResourceId.java | 34 + .../services/rest/ext/groovy/SourceFile.java | 33 + .../rest/ext/groovy/SourceFolder.java | 33 + .../groovy/GroovyScriptInstantiator.java | 302 +++ .../groovy/GroovyScriptJarJarPlugin.java | 83 + .../groovy/GroovyScriptURLLoaderPlugin.java | 76 + .../groovy/jarjar/JarJarClassLoader.java | 145 ++ .../jarjar/JarJarExpressionTransformer.java | 124 ++ .../script/groovy/jarjar/Package.java | 240 +++ .../groovy/jarjar/PackageNameVisitor.java | 96 + .../src/test/java/a/ClassLitteral.java | 32 + .../src/test/java/a/ImportedClass.java | 32 + .../src/test/java/b/ClassLitteral.java | 32 + .../src/test/java/b/ImportedClass.java | 32 + .../services/rest/ext/BaseTest.java | 67 + .../DefaultGroovyResourceLoaderTest.java | 53 + .../ext/groovy/ExtendedClassLoaderTest.java | 76 + .../ext/groovy/GroovyContextParamTest.java | 79 + .../ext/groovy/GroovyDependenciesTest.java | 62 + .../ext/groovy/GroovyExoComponentTest.java | 89 + .../rest/ext/groovy/GroovySimpleTest.java | 85 + .../services/script/groovy/Book.java | 76 + .../script/groovy/GroovyInstantiatorTest.java | 97 + .../script/groovy/SampleComponent.java | 42 + .../script/groovy/jarjar/JarJarTest.java | 93 + .../script/groovy/jarjar/Mapping.java | 55 + .../script/groovy/jarjar/TestScript.java | 87 + .../test/java/prefix1/a/ClassLitteral.java | 32 + .../test/java/prefix1/a/ImportedClass.java | 32 + .../test/java/prefix1/b/ClassLitteral.java | 32 + .../test/java/prefix1/b/ImportedClass.java | 32 + .../test/java/prefix2/a/ClassLitteral.java | 32 + .../test/java/prefix2/a/ImportedClass.java | 32 + .../test/java/prefix2/b/ClassLitteral.java | 32 + .../test/java/prefix2/b/ImportedClass.java | 32 + .../src/test/resources/Book.groovy | 8 + .../src/test/resources/TestInjection.groovy | 12 + .../src/test/resources/TestJarJar.groovy | 13 + .../resources/TestSimpleXMLGenerator.groovy | 18 + .../conf/standalone/test-configuration.xml | 26 + .../resources/jarjar/classlitteral1.groovy | 2 + .../resources/jarjar/classlitteral2.groovy | 2 + .../resources/jarjar/classlitteral_1.groovy | 2 + .../resources/jarjar/classlitteral_2.groovy | 2 + .../src/test/resources/jarjar/import1.groovy | 3 + .../src/test/resources/jarjar/import2.groovy | 3 + exo.jcr.component.webdav/pom.xml | 17 +- .../ext/provider/XSLTStreamingOutput.java | 136 ++ .../services/rest/ext/webdav/method/ACL.java | 41 + .../rest/ext/webdav/method/CHECKIN.java | 36 + .../rest/ext/webdav/method/CHECKOUT.java | 37 + .../services/rest/ext/webdav/method/COPY.java | 36 + .../services/rest/ext/webdav/method/LOCK.java | 36 + .../rest/ext/webdav/method/MKCOL.java | 36 + .../services/rest/ext/webdav/method/MOVE.java | 36 + .../rest/ext/webdav/method/OPTIONS.java | 36 + .../rest/ext/webdav/method/ORDERPATCH.java | 36 + .../rest/ext/webdav/method/PROPFIND.java | 36 + .../rest/ext/webdav/method/PROPPATCH.java | 36 + .../rest/ext/webdav/method/REPORT.java | 36 + .../rest/ext/webdav/method/SEARCH.java | 36 + .../rest/ext/webdav/method/UNCHECKOUT.java | 36 + .../rest/ext/webdav/method/UNLOCK.java | 36 + .../ext/webdav/method/VERSIONCONTROL.java | 36 + .../xml/resolving/XMLResolvingService.java | 40 + .../impl/AddXMLResolvingContextPlugin.java | 69 + .../xml/resolving/impl/XMLResolver.java | 89 + .../impl/XMLResolvingServiceImpl.java | 89 + .../xml/transform/AbstractTransformer.java | 54 + .../services/xml/transform/EncodingMap.java | 37 + .../NotSupportedIOTypeException.java | 62 + .../xml/transform/PipeTransformer.java | 33 + .../xml/transform/impl/EncodingMapImpl.java | 448 +++++ .../xml/transform/impl/TransformerBase.java | 270 +++ .../impl/trax/TRAXTemplatesImpl.java | 64 + .../impl/trax/TRAXTemplatesLoaderPlugin.java | 52 + .../impl/trax/TRAXTemplatesServiceImpl.java | 162 ++ .../impl/trax/TRAXTransformerImpl.java | 228 +++ .../impl/trax/TRAXTransformerServiceImpl.java | 127 ++ .../xml/transform/trax/Constants.java | 35 + .../xml/transform/trax/TRAXTemplates.java | 44 + .../transform/trax/TRAXTemplatesService.java | 56 + .../xml/transform/trax/TRAXTransformer.java | 94 + .../trax/TRAXTransformerService.java | 44 + .../main/resources/CatalogManager.properties | 9 + .../main/resources/catalog/exo-catalog.xml | 29 + .../src/main/resources/conf/configuration.xml | 89 + .../resources/conf/portal/configuration.xml | 70 + .../src/main/resources/dtd/XMLSchema.dtd | 402 ++++ .../src/main/resources/dtd/datatypes.dtd | 203 ++ .../src/main/resources/dtd/j2ee_1_4.xsd | 1674 +++++++++++++++++ .../dtd/j2ee_web_services_client_1_1.xsd | 355 ++++ .../src/main/resources/dtd/jsp_2_0.xsd | 313 +++ .../src/main/resources/dtd/web-app_2_3.dtd | 1063 +++++++++++ .../src/main/resources/dtd/web-app_2_4.xsd | 1279 +++++++++++++ .../src/main/resources/dtd/xhtml-lat1.ent | 196 ++ .../src/main/resources/dtd/xhtml-special.ent | 80 + .../src/main/resources/dtd/xhtml-symbol.ent | 237 +++ .../main/resources/dtd/xhtml1-frameset.dtd | 1235 ++++++++++++ .../src/main/resources/dtd/xhtml1-strict.dtd | 978 ++++++++++ .../resources/dtd/xhtml1-transitional.dtd | 1201 ++++++++++++ .../src/main/resources/dtd/xml.xsd | 120 ++ .../main/resources/xslt/html-url-rewite.xsl | 156 ++ .../conf/standalone/test-configuration.xml | 218 +++ .../src/test/resources/dtd-not-found.xml | 27 + .../src/test/resources/html-url-rewite.xsl | 156 ++ .../src/test/resources/rss-in.html | 43 + .../src/test/resources/rss-in.xhtml | 127 ++ .../src/test/resources/test.policy | 11 + .../src/test/resources/web-app_2_3.dtd | 1063 +++++++++++ .../src/test/resources/web.xml | 43 + .../src/main/assemblies/jcr-addon-package.xml | 8 - 134 files changed, 20930 insertions(+), 22 deletions(-) create mode 100644 exo.jcr.component.core/src/main/java/org/exoplatform/services/jdbc/DataSourceProvider.java create mode 100644 exo.jcr.component.core/src/main/java/org/exoplatform/services/jdbc/impl/DataSourceProviderImpl.java create mode 100644 exo.jcr.component.core/src/main/java/org/exoplatform/services/jdbc/impl/ManagedConnection.java create mode 100644 exo.jcr.component.core/src/main/java/org/exoplatform/services/jdbc/impl/ManagedDataSource.java create mode 100644 exo.jcr.component.core/src/main/java/org/exoplatform/services/rpc/RPCException.java create mode 100644 exo.jcr.component.core/src/main/java/org/exoplatform/services/rpc/RPCService.java create mode 100644 exo.jcr.component.core/src/main/java/org/exoplatform/services/rpc/RemoteCommand.java create mode 100644 exo.jcr.component.core/src/main/java/org/exoplatform/services/rpc/SingleMethodCallCommand.java create mode 100644 exo.jcr.component.core/src/main/java/org/exoplatform/services/rpc/TopologyChangeEvent.java create mode 100644 exo.jcr.component.core/src/main/java/org/exoplatform/services/rpc/TopologyChangeListener.java create mode 100644 exo.jcr.component.core/src/main/java/org/exoplatform/services/rpc/impl/AbstractRPCService.java create mode 100644 exo.jcr.component.core/src/main/java/org/exoplatform/services/rpc/jgv3/RPCServiceImpl.java create mode 100644 exo.jcr.component.core/src/main/java/org/exoplatform/services/transaction/ActionNonTxAware.java create mode 100644 exo.jcr.component.ext/src/main/java/org/exoplatform/services/rest/ext/groovy/BaseResourceId.java create mode 100644 exo.jcr.component.ext/src/main/java/org/exoplatform/services/rest/ext/groovy/ClassPathEntry.java create mode 100644 exo.jcr.component.ext/src/main/java/org/exoplatform/services/rest/ext/groovy/DefaultGroovyResourceLoader.java create mode 100644 exo.jcr.component.ext/src/main/java/org/exoplatform/services/rest/ext/groovy/ExtendedGroovyClassLoader.java create mode 100644 exo.jcr.component.ext/src/main/java/org/exoplatform/services/rest/ext/groovy/GroovyClassLoaderProvider.java create mode 100644 exo.jcr.component.ext/src/main/java/org/exoplatform/services/rest/ext/groovy/GroovyJaxrsPublisher.java create mode 100644 exo.jcr.component.ext/src/main/java/org/exoplatform/services/rest/ext/groovy/MalformedScriptException.java create mode 100644 exo.jcr.component.ext/src/main/java/org/exoplatform/services/rest/ext/groovy/ResourceId.java create mode 100644 exo.jcr.component.ext/src/main/java/org/exoplatform/services/rest/ext/groovy/SourceFile.java create mode 100644 exo.jcr.component.ext/src/main/java/org/exoplatform/services/rest/ext/groovy/SourceFolder.java create mode 100644 exo.jcr.component.ext/src/main/java/org/exoplatform/services/script/groovy/GroovyScriptInstantiator.java create mode 100644 exo.jcr.component.ext/src/main/java/org/exoplatform/services/script/groovy/GroovyScriptJarJarPlugin.java create mode 100644 exo.jcr.component.ext/src/main/java/org/exoplatform/services/script/groovy/GroovyScriptURLLoaderPlugin.java create mode 100644 exo.jcr.component.ext/src/main/java/org/exoplatform/services/script/groovy/jarjar/JarJarClassLoader.java create mode 100644 exo.jcr.component.ext/src/main/java/org/exoplatform/services/script/groovy/jarjar/JarJarExpressionTransformer.java create mode 100644 exo.jcr.component.ext/src/main/java/org/exoplatform/services/script/groovy/jarjar/Package.java create mode 100644 exo.jcr.component.ext/src/main/java/org/exoplatform/services/script/groovy/jarjar/PackageNameVisitor.java create mode 100644 exo.jcr.component.ext/src/test/java/a/ClassLitteral.java create mode 100644 exo.jcr.component.ext/src/test/java/a/ImportedClass.java create mode 100644 exo.jcr.component.ext/src/test/java/b/ClassLitteral.java create mode 100644 exo.jcr.component.ext/src/test/java/b/ImportedClass.java create mode 100644 exo.jcr.component.ext/src/test/java/org/exoplatform/services/rest/ext/BaseTest.java create mode 100644 exo.jcr.component.ext/src/test/java/org/exoplatform/services/rest/ext/groovy/DefaultGroovyResourceLoaderTest.java create mode 100644 exo.jcr.component.ext/src/test/java/org/exoplatform/services/rest/ext/groovy/ExtendedClassLoaderTest.java create mode 100644 exo.jcr.component.ext/src/test/java/org/exoplatform/services/rest/ext/groovy/GroovyContextParamTest.java create mode 100644 exo.jcr.component.ext/src/test/java/org/exoplatform/services/rest/ext/groovy/GroovyDependenciesTest.java create mode 100644 exo.jcr.component.ext/src/test/java/org/exoplatform/services/rest/ext/groovy/GroovyExoComponentTest.java create mode 100644 exo.jcr.component.ext/src/test/java/org/exoplatform/services/rest/ext/groovy/GroovySimpleTest.java create mode 100644 exo.jcr.component.ext/src/test/java/org/exoplatform/services/script/groovy/Book.java create mode 100644 exo.jcr.component.ext/src/test/java/org/exoplatform/services/script/groovy/GroovyInstantiatorTest.java create mode 100644 exo.jcr.component.ext/src/test/java/org/exoplatform/services/script/groovy/SampleComponent.java create mode 100644 exo.jcr.component.ext/src/test/java/org/exoplatform/services/script/groovy/jarjar/JarJarTest.java create mode 100644 exo.jcr.component.ext/src/test/java/org/exoplatform/services/script/groovy/jarjar/Mapping.java create mode 100644 exo.jcr.component.ext/src/test/java/org/exoplatform/services/script/groovy/jarjar/TestScript.java create mode 100644 exo.jcr.component.ext/src/test/java/prefix1/a/ClassLitteral.java create mode 100644 exo.jcr.component.ext/src/test/java/prefix1/a/ImportedClass.java create mode 100644 exo.jcr.component.ext/src/test/java/prefix1/b/ClassLitteral.java create mode 100644 exo.jcr.component.ext/src/test/java/prefix1/b/ImportedClass.java create mode 100644 exo.jcr.component.ext/src/test/java/prefix2/a/ClassLitteral.java create mode 100644 exo.jcr.component.ext/src/test/java/prefix2/a/ImportedClass.java create mode 100644 exo.jcr.component.ext/src/test/java/prefix2/b/ClassLitteral.java create mode 100644 exo.jcr.component.ext/src/test/java/prefix2/b/ImportedClass.java create mode 100644 exo.jcr.component.ext/src/test/resources/Book.groovy create mode 100644 exo.jcr.component.ext/src/test/resources/TestInjection.groovy create mode 100644 exo.jcr.component.ext/src/test/resources/TestJarJar.groovy create mode 100644 exo.jcr.component.ext/src/test/resources/TestSimpleXMLGenerator.groovy create mode 100644 exo.jcr.component.ext/src/test/resources/jarjar/classlitteral1.groovy create mode 100644 exo.jcr.component.ext/src/test/resources/jarjar/classlitteral2.groovy create mode 100644 exo.jcr.component.ext/src/test/resources/jarjar/classlitteral_1.groovy create mode 100644 exo.jcr.component.ext/src/test/resources/jarjar/classlitteral_2.groovy create mode 100644 exo.jcr.component.ext/src/test/resources/jarjar/import1.groovy create mode 100644 exo.jcr.component.ext/src/test/resources/jarjar/import2.groovy create mode 100644 exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/provider/XSLTStreamingOutput.java create mode 100644 exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/webdav/method/ACL.java create mode 100644 exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/webdav/method/CHECKIN.java create mode 100644 exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/webdav/method/CHECKOUT.java create mode 100644 exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/webdav/method/COPY.java create mode 100644 exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/webdav/method/LOCK.java create mode 100644 exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/webdav/method/MKCOL.java create mode 100644 exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/webdav/method/MOVE.java create mode 100644 exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/webdav/method/OPTIONS.java create mode 100644 exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/webdav/method/ORDERPATCH.java create mode 100644 exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/webdav/method/PROPFIND.java create mode 100644 exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/webdav/method/PROPPATCH.java create mode 100644 exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/webdav/method/REPORT.java create mode 100644 exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/webdav/method/SEARCH.java create mode 100644 exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/webdav/method/UNCHECKOUT.java create mode 100644 exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/webdav/method/UNLOCK.java create mode 100644 exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/webdav/method/VERSIONCONTROL.java create mode 100644 exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/resolving/XMLResolvingService.java create mode 100644 exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/resolving/impl/AddXMLResolvingContextPlugin.java create mode 100644 exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/resolving/impl/XMLResolver.java create mode 100644 exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/resolving/impl/XMLResolvingServiceImpl.java create mode 100644 exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/transform/AbstractTransformer.java create mode 100644 exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/transform/EncodingMap.java create mode 100644 exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/transform/NotSupportedIOTypeException.java create mode 100644 exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/transform/PipeTransformer.java create mode 100644 exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/transform/impl/EncodingMapImpl.java create mode 100644 exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/transform/impl/TransformerBase.java create mode 100644 exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/transform/impl/trax/TRAXTemplatesImpl.java create mode 100644 exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/transform/impl/trax/TRAXTemplatesLoaderPlugin.java create mode 100644 exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/transform/impl/trax/TRAXTemplatesServiceImpl.java create mode 100644 exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/transform/impl/trax/TRAXTransformerImpl.java create mode 100644 exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/transform/impl/trax/TRAXTransformerServiceImpl.java create mode 100644 exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/transform/trax/Constants.java create mode 100644 exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/transform/trax/TRAXTemplates.java create mode 100644 exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/transform/trax/TRAXTemplatesService.java create mode 100644 exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/transform/trax/TRAXTransformer.java create mode 100644 exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/transform/trax/TRAXTransformerService.java create mode 100644 exo.jcr.component.webdav/src/main/resources/CatalogManager.properties create mode 100644 exo.jcr.component.webdav/src/main/resources/catalog/exo-catalog.xml create mode 100644 exo.jcr.component.webdav/src/main/resources/conf/configuration.xml create mode 100644 exo.jcr.component.webdav/src/main/resources/dtd/XMLSchema.dtd create mode 100644 exo.jcr.component.webdav/src/main/resources/dtd/datatypes.dtd create mode 100644 exo.jcr.component.webdav/src/main/resources/dtd/j2ee_1_4.xsd create mode 100644 exo.jcr.component.webdav/src/main/resources/dtd/j2ee_web_services_client_1_1.xsd create mode 100644 exo.jcr.component.webdav/src/main/resources/dtd/jsp_2_0.xsd create mode 100644 exo.jcr.component.webdav/src/main/resources/dtd/web-app_2_3.dtd create mode 100644 exo.jcr.component.webdav/src/main/resources/dtd/web-app_2_4.xsd create mode 100644 exo.jcr.component.webdav/src/main/resources/dtd/xhtml-lat1.ent create mode 100644 exo.jcr.component.webdav/src/main/resources/dtd/xhtml-special.ent create mode 100644 exo.jcr.component.webdav/src/main/resources/dtd/xhtml-symbol.ent create mode 100644 exo.jcr.component.webdav/src/main/resources/dtd/xhtml1-frameset.dtd create mode 100644 exo.jcr.component.webdav/src/main/resources/dtd/xhtml1-strict.dtd create mode 100644 exo.jcr.component.webdav/src/main/resources/dtd/xhtml1-transitional.dtd create mode 100644 exo.jcr.component.webdav/src/main/resources/dtd/xml.xsd create mode 100644 exo.jcr.component.webdav/src/main/resources/xslt/html-url-rewite.xsl create mode 100644 exo.jcr.component.webdav/src/test/resources/dtd-not-found.xml create mode 100644 exo.jcr.component.webdav/src/test/resources/html-url-rewite.xsl create mode 100644 exo.jcr.component.webdav/src/test/resources/rss-in.html create mode 100644 exo.jcr.component.webdav/src/test/resources/rss-in.xhtml create mode 100644 exo.jcr.component.webdav/src/test/resources/test.policy create mode 100644 exo.jcr.component.webdav/src/test/resources/web-app_2_3.dtd create mode 100644 exo.jcr.component.webdav/src/test/resources/web.xml diff --git a/exo.jcr.component.core/pom.xml b/exo.jcr.component.core/pom.xml index dc7b5d641c..a70d679ebd 100644 --- a/exo.jcr.component.core/pom.xml +++ b/exo.jcr.component.core/pom.xml @@ -59,7 +59,7 @@ test - io.meeds.kernel + org.exoplatform.commons-exo exo.kernel.component.command @@ -75,7 +75,7 @@ exo.core.component.organization.api - io.meeds.core + org.exoplatform.commons-exo exo.core.component.database @@ -274,7 +274,7 @@ - io.meeds.kernel + org.exoplatform.commons-exo exo.kernel.component.ext.cache.impl.infinispan.v8 diff --git a/exo.jcr.component.core/src/main/java/org/exoplatform/services/jdbc/DataSourceProvider.java b/exo.jcr.component.core/src/main/java/org/exoplatform/services/jdbc/DataSourceProvider.java new file mode 100644 index 0000000000..4a05e3dd38 --- /dev/null +++ b/exo.jcr.component.core/src/main/java/org/exoplatform/services/jdbc/DataSourceProvider.java @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2011 eXo Platform SAS. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.exoplatform.services.jdbc; + +import org.exoplatform.container.spi.DefinitionByType; +import org.exoplatform.services.jdbc.impl.DataSourceProviderImpl; + +import javax.naming.NamingException; +import javax.sql.DataSource; + +/** + * This provider is used to get a {@link DataSource} in an uniform manner. + * It allows to wrap the {@link DataSource} in case it is defined as managed + * + * @author Nicolas Filotto + * @version $Id$ + * + */ +@DefinitionByType(type = DataSourceProviderImpl.class) +public interface DataSourceProvider +{ + /** + * Try to get the data source from a lookup, if it can't a {@link NamingException} + * will be thrown + * @param dataSourceName the name of the data source to lookup + * @return the {@link DataSource} found thanks to the lookup. The original + * object could be wrap to another {@link DataSource} in order to support + * managed data source. + * @throws NamingException if the data source could not be found + */ + DataSource getDataSource(String dataSourceName) throws NamingException; + + /** + * Indicates whether or not the given data source is managed + * @param dataSourceName the data source to check + * @return true if the data source is managed, + * false otherwise + */ + boolean isManaged(String dataSourceName); +} diff --git a/exo.jcr.component.core/src/main/java/org/exoplatform/services/jdbc/impl/DataSourceProviderImpl.java b/exo.jcr.component.core/src/main/java/org/exoplatform/services/jdbc/impl/DataSourceProviderImpl.java new file mode 100644 index 0000000000..0701d4cee0 --- /dev/null +++ b/exo.jcr.component.core/src/main/java/org/exoplatform/services/jdbc/impl/DataSourceProviderImpl.java @@ -0,0 +1,182 @@ +/* + * Copyright (C) 2011 eXo Platform SAS. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.exoplatform.services.jdbc.impl; + +import org.exoplatform.container.xml.InitParams; +import org.exoplatform.container.xml.ValueParam; +import org.exoplatform.container.xml.ValuesParam; +import org.exoplatform.services.jdbc.DataSourceProvider; +import org.exoplatform.services.log.ExoLogger; +import org.exoplatform.services.log.Log; +import org.exoplatform.services.transaction.TransactionService; + +import java.util.HashSet; +import java.util.Set; +import java.util.StringTokenizer; + +import javax.naming.InitialContext; +import javax.naming.NamingException; +import javax.sql.DataSource; +import javax.transaction.TransactionManager; + +/** + * The default implementation of {@link DataSourceProvider}. It allows you + * to define a data source as managed thanks to the configuration of this + * component. When the data source is declared as managed, the {@link DataSource} + * object will be wrap into a {@link ManagedDataSource}. + * + * @author Nicolas Filotto + * @version $Id$ + * + */ +public class DataSourceProviderImpl implements DataSourceProvider +{ + + /** + * Logger + */ + private static final Log LOG = ExoLogger.getLogger("exo.kernel.component.common.DataSourceProviderImpl"); + + /** + * The name of the parameter to know if the tx has to be checked or not. + */ + protected static final String PARAM_CHECK_TX = "check-tx-active"; + + /** + * The name of the parameter to know if the data sources are always managed. + */ + protected static final String PARAM_ALWAYS_MANAGED = "always-managed"; + + /** + * The name of the parameter of all the managed data sources. + */ + protected static final String PARAM_MANAGED_DS = "managed-data-sources"; + + /** + * The transaction manager + */ + protected final TransactionManager tm; + + /** + * Indicates if the data source needs to check if a tx is active + * to decide if the provided connection needs to be managed or not. + * If it is set to false, the data source will provide only + * managed connections if the data source itself is managed. + */ + protected boolean checkIfTxActive = true; + + /** + * Indicates that all the data sources are managed + */ + protected boolean alwaysManaged; + + /** + * A set of all the data sources that are managed + */ + protected final Set managedDS = new HashSet(); + + /** + * The default constructor + */ + public DataSourceProviderImpl(InitParams params) + { + this(params, null); + } + + /** + * The default constructor + */ + public DataSourceProviderImpl(InitParams params, TransactionService tService) + { + this.tm = tService == null ? null : tService.getTransactionManager(); + if (params != null) + { + ValueParam param = params.getValueParam(PARAM_CHECK_TX); + if (param != null) + { + this.checkIfTxActive = Boolean.valueOf(param.getValue()); + } + param = params.getValueParam(PARAM_ALWAYS_MANAGED); + if (param != null && Boolean.valueOf(param.getValue())) + { + this.alwaysManaged = true; + return; + } + ValuesParam vp = params.getValuesParam(PARAM_MANAGED_DS); + if (vp != null && vp.getValues() != null) + { + for (Object oValue : vp.getValues()) + { + String s = (String)oValue; + StringTokenizer st = new StringTokenizer(s, ","); + while (st.hasMoreTokens()) + { + String dsName = st.nextToken().trim(); + if (!dsName.isEmpty()) + { + managedDS.add(dsName); + } + } + } + } + } + } + + /** + * @throws NamingException + * @see org.exoplatform.services.jdbc.DataSourceProvider#getDataSource(java.lang.String) + */ + public DataSource getDataSource(String dataSourceName) throws NamingException + { + InitialContext ctx = new InitialContext(); + try + { + DataSource ds = (DataSource)ctx.lookup(dataSourceName); + // wrap the data source object if it is managed + return isManaged(dataSourceName) ? new ManagedDataSource(ds, tm, checkIfTxActive) : ds; + } + finally + { + try + { + ctx.close(); + } + catch (NamingException e) + { + LOG.warn("Failed to close naming context.", e); + } + } + } + + /** + * @see org.exoplatform.services.jdbc.DataSourceProvider#isManaged(java.lang.String) + */ + public boolean isManaged(String dataSourceName) + { + if (alwaysManaged) + { + return true; + } + else if (managedDS.isEmpty()) + { + return false; + } + return managedDS.contains(dataSourceName); + } +} diff --git a/exo.jcr.component.core/src/main/java/org/exoplatform/services/jdbc/impl/ManagedConnection.java b/exo.jcr.component.core/src/main/java/org/exoplatform/services/jdbc/impl/ManagedConnection.java new file mode 100644 index 0000000000..340c52f9e3 --- /dev/null +++ b/exo.jcr.component.core/src/main/java/org/exoplatform/services/jdbc/impl/ManagedConnection.java @@ -0,0 +1,574 @@ +/* + * Copyright (C) 2011 eXo Platform SAS. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.exoplatform.services.jdbc.impl; + +import org.exoplatform.services.log.ExoLogger; +import org.exoplatform.services.log.Log; + +import java.lang.reflect.Method; +import java.sql.Array; +import java.sql.Blob; +import java.sql.CallableStatement; +import java.sql.Clob; +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.NClob; +import java.sql.PreparedStatement; +import java.sql.SQLClientInfoException; +import java.sql.SQLException; +import java.sql.SQLWarning; +import java.sql.SQLXML; +import java.sql.Savepoint; +import java.sql.Statement; +import java.sql.Struct; +import java.util.Map; +import java.util.Properties; +import java.util.concurrent.Executor; + +/** + * This classes wraps a jdbc connection in order to prevent any forbidden + * actions such as explicit commit/rollback. + * + * @author Nicolas Filotto + * @version $Id$ + * + */ +public class ManagedConnection implements Connection +{ + /** + * The logger + */ + private static final Log LOG = ExoLogger.getLogger("exo.kernel.component.common.ManagedConnection"); + + /** + * The nested connection + */ + private final Connection con; + + /** + * default constructor + */ + public ManagedConnection(Connection con) + { + this.con = con; + } + + /** + * @see java.sql.Wrapper#isWrapperFor(java.lang.Class) + */ + public boolean isWrapperFor(Class iface) throws SQLException + { + return con.isWrapperFor(iface); + } + + /** + * @see java.sql.Wrapper#unwrap(java.lang.Class) + */ + public T unwrap(Class iface) throws SQLException + { + return con.unwrap(iface); + } + + /** + * @see java.sql.Connection#prepareStatement(java.lang.String) + */ + public PreparedStatement prepareStatement(String sql) throws SQLException + { + return con.prepareStatement(sql); + } + + /** + * @see java.sql.Connection#prepareCall(java.lang.String) + */ + public CallableStatement prepareCall(String sql) throws SQLException + { + return con.prepareCall(sql); + } + + /** + * @see java.sql.Connection#nativeSQL(java.lang.String) + */ + public String nativeSQL(String sql) throws SQLException + { + return con.nativeSQL(sql); + } + + /** + * @see java.sql.Connection#setAutoCommit(boolean) + */ + public void setAutoCommit(boolean autoCommit) throws SQLException + { + con.setAutoCommit(autoCommit); + } + + /** + * @see java.sql.Connection#commit() + */ + public void commit() throws SQLException + { + // We cannot call commit explicitly, it will be done by the AS itself + } + + /** + * @see java.sql.Connection#rollback() + */ + public void rollback() throws SQLException + { + // We cannot call rollback explicitly, it will be done by the AS itself + } + + /** + * @see java.sql.Connection#close() + */ + public void close() throws SQLException + { + con.close(); + } + + /** + * @see java.sql.Connection#setReadOnly(boolean) + */ + public void setReadOnly(boolean readOnly) throws SQLException + { + con.setReadOnly(readOnly); + } + + /** + * @see java.sql.Connection#setCatalog(java.lang.String) + */ + public void setCatalog(String catalog) throws SQLException + { + con.setCatalog(catalog); + } + + /** + * @see java.sql.Connection#setTransactionIsolation(int) + */ + public void setTransactionIsolation(int level) throws SQLException + { + con.setTransactionIsolation(level); + } + + /** + * @see java.sql.Connection#clearWarnings() + */ + public void clearWarnings() throws SQLException + { + con.clearWarnings(); + } + + /** + * @see java.sql.Connection#createArrayOf(java.lang.String, java.lang.Object[]) + */ + public Array createArrayOf(String typeName, Object[] elements) throws SQLException + { + return con.createArrayOf(typeName, elements); + } + + /** + * @see java.sql.Connection#createBlob() + */ + public Blob createBlob() throws SQLException + { + return con.createBlob(); + } + + /** + * @see java.sql.Connection#createClob() + */ + public Clob createClob() throws SQLException + { + return con.createClob(); + } + + /** + * @see java.sql.Connection#createNClob() + */ + public NClob createNClob() throws SQLException + { + return con.createNClob(); + } + + /** + * @see java.sql.Connection#createSQLXML() + */ + public SQLXML createSQLXML() throws SQLException + { + return con.createSQLXML(); + } + + /** + * @see java.sql.Connection#createStatement() + */ + public Statement createStatement() throws SQLException + { + return con.createStatement(); + } + + /** + * @see java.sql.Connection#createStatement(int, int) + */ + public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException + { + return con.createStatement(resultSetType, resultSetConcurrency); + } + + /** + * @see java.sql.Connection#prepareStatement(java.lang.String, int, int) + */ + public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) + throws SQLException + { + return con.prepareStatement(sql, resultSetType, resultSetConcurrency); + } + + /** + * @see java.sql.Connection#prepareCall(java.lang.String, int, int) + */ + public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException + { + return con.prepareCall(sql, resultSetType, resultSetConcurrency); + } + + /** + * @see java.sql.Connection#setTypeMap(java.util.Map) + */ + public void setTypeMap(Map> map) throws SQLException + { + con.setTypeMap(map); + } + + /** + * @see java.sql.Connection#setSavepoint() + */ + public Savepoint setSavepoint() throws SQLException + { + return con.setSavepoint(); + } + + /** + * @see java.sql.Connection#setSavepoint(java.lang.String) + */ + public Savepoint setSavepoint(String name) throws SQLException + { + return con.setSavepoint(name); + } + + /** + * @see java.sql.Connection#rollback(java.sql.Savepoint) + */ + public void rollback(Savepoint savepoint) throws SQLException + { + // We cannot call rollback explicitly, it will be done by the AS itself + } + + /** + * @see java.sql.Connection#releaseSavepoint(java.sql.Savepoint) + */ + public void releaseSavepoint(Savepoint savepoint) throws SQLException + { + con.releaseSavepoint(savepoint); + } + + /** + * @see java.sql.Connection#createStatement(int, int, int) + */ + public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) + throws SQLException + { + return con.createStatement(resultSetType, resultSetConcurrency, resultSetHoldability); + } + + /** + * @see java.sql.Connection#createStruct(java.lang.String, java.lang.Object[]) + */ + public Struct createStruct(String typeName, Object[] attributes) throws SQLException + { + return con.createStruct(typeName, attributes); + } + + /** + * @see java.sql.Connection#getAutoCommit() + */ + public boolean getAutoCommit() throws SQLException + { + return con.getAutoCommit(); + } + + /** + * @see java.sql.Connection#isClosed() + */ + public boolean isClosed() throws SQLException + { + return con.isClosed(); + } + + /** + * @see java.sql.Connection#isReadOnly() + */ + public boolean isReadOnly() throws SQLException + { + return con.isReadOnly(); + } + + /** + * @see java.sql.Connection#getCatalog() + */ + public String getCatalog() throws SQLException + { + return con.getCatalog(); + } + + /** + * @see java.sql.Connection#getClientInfo() + */ + public Properties getClientInfo() throws SQLException + { + return con.getClientInfo(); + } + + /** + * @see java.sql.Connection#getClientInfo(java.lang.String) + */ + public String getClientInfo(String name) throws SQLException + { + return con.getClientInfo(name); + } + + /** + * @see java.sql.Connection#getMetaData() + */ + public DatabaseMetaData getMetaData() throws SQLException + { + return con.getMetaData(); + } + + /** + * @see java.sql.Connection#getTransactionIsolation() + */ + public int getTransactionIsolation() throws SQLException + { + return con.getTransactionIsolation(); + } + + /** + * @see java.sql.Connection#getWarnings() + */ + public SQLWarning getWarnings() throws SQLException + { + return con.getWarnings(); + } + + /** + * @see java.sql.Connection#getTypeMap() + */ + public Map> getTypeMap() throws SQLException + { + return con.getTypeMap(); + } + + /** + * @see java.sql.Connection#getHoldability() + */ + public int getHoldability() throws SQLException + { + return con.getHoldability(); + } + + /** + * @see java.sql.Connection#isValid(int) + */ + public boolean isValid(int timeout) throws SQLException + { + return con.isValid(timeout); + } + + /** + * @see java.sql.Connection#prepareStatement(java.lang.String, int, int, int) + */ + public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, + int resultSetHoldability) throws SQLException + { + return con.prepareStatement(sql, resultSetType, resultSetConcurrency, resultSetHoldability); + } + + /** + * @see java.sql.Connection#prepareCall(java.lang.String, int, int, int) + */ + public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, + int resultSetHoldability) throws SQLException + { + return con.prepareCall(sql, resultSetType, resultSetConcurrency, resultSetHoldability); + } + + /** + * @see java.sql.Connection#prepareStatement(java.lang.String, int) + */ + public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException + { + return con.prepareStatement(sql, autoGeneratedKeys); + } + + /** + * @see java.sql.Connection#prepareStatement(java.lang.String, int[]) + */ + public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException + { + return con.prepareStatement(sql, columnIndexes); + } + + /** + * @see java.sql.Connection#prepareStatement(java.lang.String, java.lang.String[]) + */ + public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException + { + return con.prepareStatement(sql, columnNames); + } + + /** + * @see java.sql.Connection#setClientInfo(java.util.Properties) + */ + public void setClientInfo(Properties properties) throws SQLClientInfoException + { + con.setClientInfo(properties); + } + + /** + * @see java.sql.Connection#setClientInfo(java.lang.String, java.lang.String) + */ + public void setClientInfo(String name, String value) throws SQLClientInfoException + { + con.setClientInfo(name, value); + } + + /** + * @see java.sql.Connection#setHoldability(int) + */ + public void setHoldability(int holdability) throws SQLException + { + con.setHoldability(holdability); + } + + /** + * @see java.sql.Connection#setSchema(java.lang.String) + */ + public void setSchema(String schema) throws SQLException + { + try + { + Method m = con.getClass().getMethod("setSchema", String.class); + m.invoke(con, schema); + } + catch (NoSuchMethodException e) + { + LOG.debug("The method setSchema cannot be found in the class " + con.getClass() + + ", so we assume it is not supported"); + } + catch (Exception e) + { + throw new SQLException(e); + } + } + + /** + * @see java.sql.Connection#getSchema() + */ + public String getSchema() throws SQLException + { + try + { + Method m = con.getClass().getMethod("getSchema"); + return (String)m.invoke(con); + } + catch (NoSuchMethodException e) + { + LOG.debug("The method getSchema cannot be found in the class " + con.getClass() + + ", so we assume it is not supported"); + } + catch (Exception e) + { + throw new SQLException(e); + } + return null; + } + + /** + * @see java.sql.Connection#abort(java.util.concurrent.Executor) + */ + public void abort(Executor executor) throws SQLException + { + try + { + Method m = con.getClass().getMethod("abort", Executor.class); + m.invoke(con, executor); + } + catch (NoSuchMethodException e) + { + LOG.debug("The method abort cannot be found in the class " + con.getClass() + + ", so we assume it is not supported"); + } + catch (Exception e) + { + throw new SQLException(e); + } + } + + /** + * @see java.sql.Connection#setNetworkTimeout(java.util.concurrent.Executor, int) + */ + public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException + { + try + { + Method m = con.getClass().getMethod("setNetworkTimeout", Executor.class, int.class); + m.invoke(con, executor, milliseconds); + } + catch (NoSuchMethodException e) + { + LOG.debug("The method setNetworkTimeout cannot be found in the class " + con.getClass() + + ", so we assume it is not supported"); + } + catch (Exception e) + { + throw new SQLException(e); + } + } + + /** + * @see java.sql.Connection#getNetworkTimeout() + */ + public int getNetworkTimeout() throws SQLException + { + try + { + Method m = con.getClass().getMethod("getNetworkTimeout"); + return (Integer)m.invoke(con); + } + catch (NoSuchMethodException e) + { + LOG.debug("The method getNetworkTimeout cannot be found in the class " + con.getClass() + + ", so we assume it is not supported"); + } + catch (Exception e) + { + throw new SQLException(e); + } + return 0; + } +} diff --git a/exo.jcr.component.core/src/main/java/org/exoplatform/services/jdbc/impl/ManagedDataSource.java b/exo.jcr.component.core/src/main/java/org/exoplatform/services/jdbc/impl/ManagedDataSource.java new file mode 100644 index 0000000000..fb50ea5cf2 --- /dev/null +++ b/exo.jcr.component.core/src/main/java/org/exoplatform/services/jdbc/impl/ManagedDataSource.java @@ -0,0 +1,182 @@ +/* + * Copyright (C) 2011 eXo Platform SAS. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.exoplatform.services.jdbc.impl; + +import org.exoplatform.services.log.ExoLogger; +import org.exoplatform.services.log.Log; + +import java.io.PrintWriter; +import java.lang.reflect.Method; +import java.sql.Connection; +import java.sql.SQLException; +import java.sql.SQLFeatureNotSupportedException; +import java.util.logging.Logger; + +import javax.sql.DataSource; +import javax.transaction.Status; +import javax.transaction.SystemException; +import javax.transaction.TransactionManager; + +/** + * This classes is used to wrap the original {@link DataSource} + * in order to be able to support the managed data sources with a limited + * amount of changes. A {@link DataSource} is expected to be wrapped only + * when a data source is defined and has been configured as managed + * + * @author Nicolas Filotto + * @version $Id$ + * + */ +public class ManagedDataSource implements DataSource +{ + private static final Log LOG = ExoLogger.getLogger("exo.kernel.component.common.ManagedDataSource"); + + /** + * The transaction manager + */ + private final TransactionManager tm; + + /** + * The wrapped {@link DataSource} + */ + private final DataSource ds; + + /** + * Indicates whether the tx status need to be check first to know + * if the provided connection needs to be managed or not + */ + private final boolean checkIfTxActive; + + /** + * default constructor + */ + public ManagedDataSource(DataSource ds, TransactionManager tm, boolean checkIfTxActive) + { + this.tm = tm; + this.ds = ds; + this.checkIfTxActive = checkIfTxActive; + } + + /** + * @see javax.sql.CommonDataSource#getLogWriter() + */ + public PrintWriter getLogWriter() throws SQLException + { + return ds.getLogWriter(); + } + + /** + * @see javax.sql.CommonDataSource#getLoginTimeout() + */ + public int getLoginTimeout() throws SQLException + { + return ds.getLoginTimeout(); + } + + /** + * @see javax.sql.CommonDataSource#setLogWriter(java.io.PrintWriter) + */ + public void setLogWriter(PrintWriter out) throws SQLException + { + ds.setLogWriter(out); + } + + /** + * @see javax.sql.CommonDataSource#setLoginTimeout(int) + */ + public void setLoginTimeout(int seconds) throws SQLException + { + ds.setLoginTimeout(seconds); + } + + /** + * @see java.sql.Wrapper#isWrapperFor(java.lang.Class) + */ + public boolean isWrapperFor(Class iface) throws SQLException + { + return ds.isWrapperFor(iface); + } + + /** + * @see java.sql.Wrapper#unwrap(java.lang.Class) + */ + public T unwrap(Class iface) throws SQLException + { + return ds.unwrap(iface); + } + + /** + * @see javax.sql.DataSource#getConnection() + */ + public Connection getConnection() throws SQLException + { + Connection con = ds.getConnection(); + return providesManagedConnection() ? new ManagedConnection(con) : con; + } + + /** + * @see javax.sql.DataSource#getConnection(java.lang.String, java.lang.String) + */ + public Connection getConnection(String username, String password) throws SQLException + { + Connection con = ds.getConnection(username, password); + return providesManagedConnection() ? new ManagedConnection(con) : con; + } + + /** + * Indicates whether or not a global tx is active + * @return true if a tx is active, false otherwise + */ + private boolean isTxActive() + { + try + { + return tm != null && tm.getStatus() != Status.STATUS_NO_TRANSACTION; + } + catch (SystemException e) + { + LOG.warn("We cannot know if a global tx is active", e); + } + return false; + } + + /** + * Indicates whether or not the provided connection needs to be managed + */ + private boolean providesManagedConnection() + { + return !checkIfTxActive || isTxActive(); + } + + /** + * @see javax.sql.CommonDataSource#getParentLogger() + */ + public Logger getParentLogger() throws SQLFeatureNotSupportedException + { + try + { + Method m = ds.getClass().getMethod("getParentLogger"); + return (Logger)m.invoke(ds); + } + catch (Exception e) + { + throw new SQLFeatureNotSupportedException(e); + } + } +} diff --git a/exo.jcr.component.core/src/main/java/org/exoplatform/services/rpc/RPCException.java b/exo.jcr.component.core/src/main/java/org/exoplatform/services/rpc/RPCException.java new file mode 100644 index 0000000000..6f27aa10dd --- /dev/null +++ b/exo.jcr.component.core/src/main/java/org/exoplatform/services/rpc/RPCException.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2010 eXo Platform SAS. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.exoplatform.services.rpc; + +/** + * The root class of all the Exception related to the RPC Service + * + * @author Nicolas Filotto + * @version $Id$ + */ +public class RPCException extends Exception +{ + + /** + * The serial version UID + */ + private static final long serialVersionUID = -9113831373947878170L; + + public RPCException(String message, Throwable cause) + { + super(message, cause); + } + + public RPCException(String message) + { + super(message); + } +} diff --git a/exo.jcr.component.core/src/main/java/org/exoplatform/services/rpc/RPCService.java b/exo.jcr.component.core/src/main/java/org/exoplatform/services/rpc/RPCService.java new file mode 100644 index 0000000000..015414ffc8 --- /dev/null +++ b/exo.jcr.component.core/src/main/java/org/exoplatform/services/rpc/RPCService.java @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2010 eXo Platform SAS. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.exoplatform.services.rpc; + +import java.io.Serializable; +import java.util.List; + +/** + * This service provides mechanism to communicate with the other cluster nodes. This service will + * be based of JGroups as an underlying Transport. + * @author Nicolas Filotto + * @version $Id$ + */ +public interface RPCService +{ + + /** + * The permission needed to access to any methods of the RPCService + */ + public static final RuntimePermission ACCESS_RPC_SERVICE_PERMISSION = new RuntimePermission("accessRPCService"); + + /** + * Executes a command on all the cluster nodes. This method is equivalent to the other method of the + * same type but with the default timeout. The command must be registered first otherwise an + * {@link RPCException} will be thrown. + * + * @param command The command to execute on each cluster node + * @param synchronous if true, sets group request mode to org.jgroups.blocks.GroupRequest#GET_ALL, + * and if false sets it to org.jgroups.blocks.GroupRequest#GET_NONE. + * @param args an array of {@link Serializable} objects corresponding to parameters of the command + * to execute remotely + * @return a list of responses from all the members of the cluster. If we met an exception on a given node, + * the RPCException will be the corresponding response of this particular node + * @throws RPCException in the event of problems. + * @throws SecurityException if the {@link SecurityManager} is installed and the call method + * doesn't have the {@link RuntimePermission} ACCESS_RPC_SERVICE_PERMISSION + */ + List executeCommandOnAllNodes(RemoteCommand command, boolean synchronous, Serializable... args) + throws RPCException, SecurityException; + + /** + * Executes a command synchronously on all the cluster nodes. The command must be registered first otherwise an + * {@link RPCException} will be thrown. + * + * @param command The command to execute on each cluster node + * @param timeout a timeout after which to throw a replication exception. + * @param args an array of {@link Serializable} objects corresponding to parameters of the command + * to execute remotely + * @return a list of responses from all the members of the cluster. If we met an exception on a given node, + * the RPCException will be the corresponding response of this particular node + * @throws RPCException in the event of problems. + * @throws SecurityException if the {@link SecurityManager} is installed and the call method + * doesn't have the {@link RuntimePermission} ACCESS_RPC_SERVICE_PERMISSION + */ + List executeCommandOnAllNodes(RemoteCommand command, long timeout, Serializable... args) + throws RPCException, SecurityException; + + /** + * Executes a command on the coordinator only. This method is equivalent to the other method of the + * same type but with the default timeout. The command must be registered first otherwise an + * {@link RPCException} will be thrown. + * + * @param command The command to execute on the coordinator node + * @param synchronous if true, sets group request mode to org.jgroups.blocks.GroupRequest#GET_ALL, + * and if false sets it to org.jgroups.blocks.GroupRequest#GET_NONE. + * @param args an array of {@link Serializable} objects corresponding to parameters of the command + * to execute remotely + * @return the response of the coordinator. + * @throws RPCException in the event of problems. + * @throws SecurityException if the {@link SecurityManager} is installed and the call method + * doesn't have the {@link RuntimePermission} ACCESS_RPC_SERVICE_PERMISSION + */ + Object executeCommandOnCoordinator(RemoteCommand command, boolean synchronous, Serializable... args) + throws RPCException, SecurityException; + + /** + * Executes a command synchronously on the coordinator only. The command must be registered first otherwise an + * {@link RPCException} will be thrown. + * + * @param command The command to execute on the coordinator node + * @param timeout a timeout after which to throw a replication exception. + * @param args an array of {@link Serializable} objects corresponding to parameters of the command + * to execute remotely + * @return the response of the coordinator. + * @throws RPCException in the event of problems. + * @throws SecurityException if the {@link SecurityManager} is installed and the call method + * doesn't have the {@link RuntimePermission} ACCESS_RPC_SERVICE_PERMISSION + */ + Object executeCommandOnCoordinator(RemoteCommand command, long timeout, Serializable... args) throws RPCException, + SecurityException; + + /** + * Register a new {@link RemoteCommand} instance, it will be mapped to its id. If a command with the + * same Id has already been registered, a warning will be printed into the log file and the new + * command will replace the old one. + * @param command the instance of the {@link RemoteCommand} to register + * @return the command itself if it could be registered null otherwise + * @throws SecurityException if the {@link SecurityManager} is installed and the call method + * doesn't have the {@link RuntimePermission} ACCESS_RPC_SERVICE_PERMISSION + */ + RemoteCommand registerCommand(RemoteCommand command) throws SecurityException; + + /** + * Unregister a {@link RemoteCommand} instance, if the id is known or the instance itself is known + * otherwise it will be ignored + * @param command the command to unregister + * @throws SecurityException if the {@link SecurityManager} is installed and the call method + * doesn't have the {@link RuntimePermission} ACCESS_RPC_SERVICE_PERMISSION + */ + void unregisterCommand(RemoteCommand command) throws SecurityException; + + /** + * Indicates whether the local node is the coordinator of the cluster + * @return true if the coordinator is the coordinator, false otherwise + * throws RPCException in case the {@link RPCService} is in an illegal state + */ + boolean isCoordinator() throws RPCException; + + /** + * Register a new {@link TopologyChangeListener} + * @param listener the listener to be registered + * @throws SecurityException if the {@link SecurityManager} is installed and the call method + * doesn't have the {@link RuntimePermission} ACCESS_RPC_SERVICE_PERMISSION + */ + void registerTopologyChangeListener(TopologyChangeListener listener) throws SecurityException; + + /** + * Unregister a {@link TopologyChangeListener} if it exists + * @param listener the listener to unregister + * @throws SecurityException if the {@link SecurityManager} is installed and the call method + * doesn't have the {@link RuntimePermission} ACCESS_RPC_SERVICE_PERMISSION + */ + void unregisterTopologyChangeListener(TopologyChangeListener listener) throws SecurityException; +} \ No newline at end of file diff --git a/exo.jcr.component.core/src/main/java/org/exoplatform/services/rpc/RemoteCommand.java b/exo.jcr.component.core/src/main/java/org/exoplatform/services/rpc/RemoteCommand.java new file mode 100644 index 0000000000..3201cf0847 --- /dev/null +++ b/exo.jcr.component.core/src/main/java/org/exoplatform/services/rpc/RemoteCommand.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2010 eXo Platform SAS. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.exoplatform.services.rpc; + +import java.io.Serializable; + +/** + * This class represents the command that can be executed on a remote server. + * A RemoteCommand needs to be ThreadSafe since it can be re-used by several + * threads in parallel. + * @author Nicolas Filotto + * @version $Id$ + */ +public interface RemoteCommand +{ + /** + * This method will execute the command on the local machine. + * @param args The parameters needed to execute the command + * @return arbitrary return value generated by performing this command + * @throws Throwable in the event of problems. + */ + Serializable execute(Serializable[] args) throws Throwable; + + /** + * Gives the id of the command + * @return the unique ID of the command + */ + String getId(); +} diff --git a/exo.jcr.component.core/src/main/java/org/exoplatform/services/rpc/SingleMethodCallCommand.java b/exo.jcr.component.core/src/main/java/org/exoplatform/services/rpc/SingleMethodCallCommand.java new file mode 100644 index 0000000000..f2cd9b7ad9 --- /dev/null +++ b/exo.jcr.component.core/src/main/java/org/exoplatform/services/rpc/SingleMethodCallCommand.java @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2010 eXo Platform SAS. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.exoplatform.services.rpc; + +import java.io.Serializable; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.Arrays; + +/** + * This command will allow you to call one specific method with the arguments given by the execute method + * on a component. + * + * @author Nicolas Filotto + * @version $Id$ + */ +public class SingleMethodCallCommand implements RemoteCommand +{ + + /** + * The component on which we want to execute the method + */ + private final Object component; + + /** + * The method that we want to call + */ + private final Method method; + + /** + * The id of the command + */ + private final String id; + + /** + * + * @param component the component on which we want to execute the method + * @param methodName the name of the method + * @param parameterTypes the parameter array + * @throws NoSuchMethodException if a matching method is not found. + * @exception SecurityException + * If a security manager, s, is present and any of the + * following conditions is met: + * + *
    + * + *
  • invocation of + * {@link SecurityManager #checkMemberAccess + * s.checkMemberAccess(this, Member.DECLARED)} denies + * access to the declared method + * + *
  • the caller's class loader is not the same as or an + * ancestor of the class loader for the current class and + * invocation of {@link SecurityManager#checkPackageAccess + * s.checkPackageAccess()} denies access to the package + * of this class + * + *
+ * @throws ClassNotFoundException If the last parameter type is an array and we + * cannot find the type of the array + */ + public SingleMethodCallCommand(Object component, String methodName, Class... parameterTypes) + throws SecurityException, NoSuchMethodException, ClassNotFoundException + { + if (component == null) + { + throw new IllegalArgumentException("The component cannot be null"); + } + if (methodName == null || (methodName = methodName.trim()).length() == 0) + { + throw new IllegalArgumentException("The methodName cannot be empty"); + } + this.component = component; + this.method = component.getClass().getDeclaredMethod(methodName, parameterTypes); + if (!Modifier.isPublic(method.getModifiers())) + { + throw new IllegalArgumentException("The method '" + methodName + "' is not public"); + } + this.id = getId(component, method); + } + + /** + * {@inheritDoc} + */ + public Serializable execute(Serializable[] args) throws Throwable + { + try + { + return (Serializable)method.invoke(component, (Object[])args); + } + catch (Exception e) + { + throw new Exception("Could not execute the method " + id + " with the arguments " + Arrays.toString(args), e); + } + } + + /** + * {@inheritDoc} + */ + public String getId() + { + return id; + } + + /** + * Gives a unique Id from the component and the method + */ + private static String getId(Object component, Method method) + { + StringBuilder sb = new StringBuilder(); + sb.append(component.getClass().getName()); + sb.append('.'); + sb.append(method.getName()); + sb.append('('); + boolean first = true; + for (Class c : method.getParameterTypes()) + { + if (first) + { + first = false; + } + else + { + sb.append(','); + } + sb.append(c.getSimpleName()); + } + sb.append(')'); + return sb.toString(); + } +} diff --git a/exo.jcr.component.core/src/main/java/org/exoplatform/services/rpc/TopologyChangeEvent.java b/exo.jcr.component.core/src/main/java/org/exoplatform/services/rpc/TopologyChangeEvent.java new file mode 100644 index 0000000000..834798a47a --- /dev/null +++ b/exo.jcr.component.core/src/main/java/org/exoplatform/services/rpc/TopologyChangeEvent.java @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2010 eXo Platform SAS. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.exoplatform.services.rpc; + +/** + * The event triggered anytime the cluster has changed of topology + * @author Nicolas Filotto + * @version $Id$ + * + */ +public class TopologyChangeEvent +{ + + /** + * Indicates whether the current node is the coordinator after this topology change + */ + private final boolean coordinator; + + /** + * Indicates whether the coordinator has changed + */ + private final boolean coordinatorHasChanged; + + /** + * Default constructor + * @param coordinatorHasChanged this parameter is set to true if the + * coordinator has changed, false otherwise + * @param coordinator this parameter is set to true if the current node + * is the coordinator, false otherwise + */ + public TopologyChangeEvent(boolean coordinatorHasChanged, boolean coordinator) + { + this.coordinator = coordinator; + this.coordinatorHasChanged = coordinatorHasChanged; + } + + /** + * Indicates whether the current node is the coordinator or not after the topology change + * @return true if the current node is the coordinator, false otherwise. + */ + public boolean isCoordinator() + { + return coordinator; + } + + /** + * Indicates whether the coordinator has changed after the topology change + * @return true if the coordinator has changed, false otherwise. + */ + public boolean isCoordinatorHasChanged() + { + return coordinatorHasChanged; + } +} diff --git a/exo.jcr.component.core/src/main/java/org/exoplatform/services/rpc/TopologyChangeListener.java b/exo.jcr.component.core/src/main/java/org/exoplatform/services/rpc/TopologyChangeListener.java new file mode 100644 index 0000000000..0768b6fa3e --- /dev/null +++ b/exo.jcr.component.core/src/main/java/org/exoplatform/services/rpc/TopologyChangeListener.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2010 eXo Platform SAS. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.exoplatform.services.rpc; + +/** + * This interface is used to allow some components to be notified anytime the topology + * of the cluster changes, in other words any time a member of the cluster leave or join + * the cluster. + * + * @author Nicolas Filotto + * @version $Id$ + * + */ +public interface TopologyChangeListener +{ + + /** + * Called anytime the topology of the cluster changes + * @param event the event triggered when the topology changes + */ + void onChange(TopologyChangeEvent event); +} diff --git a/exo.jcr.component.core/src/main/java/org/exoplatform/services/rpc/impl/AbstractRPCService.java b/exo.jcr.component.core/src/main/java/org/exoplatform/services/rpc/impl/AbstractRPCService.java new file mode 100644 index 0000000000..6fe6d047dd --- /dev/null +++ b/exo.jcr.component.core/src/main/java/org/exoplatform/services/rpc/impl/AbstractRPCService.java @@ -0,0 +1,982 @@ +/* + * Copyright (C) 2010 eXo Platform SAS. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.exoplatform.services.rpc.impl; + +import org.exoplatform.commons.utils.PropertyManager; +import org.exoplatform.container.ExoContainer; +import org.exoplatform.container.ExoContainerContext; +import org.exoplatform.container.configuration.ConfigurationManager; +import org.exoplatform.container.xml.InitParams; +import org.exoplatform.container.xml.ValueParam; +import org.exoplatform.services.log.ExoLogger; +import org.exoplatform.services.log.Log; +import org.exoplatform.services.rpc.RPCException; +import org.exoplatform.services.rpc.RPCService; +import org.exoplatform.services.rpc.RemoteCommand; +import org.exoplatform.services.rpc.TopologyChangeEvent; +import org.exoplatform.services.rpc.TopologyChangeListener; +import org.jgroups.Address; +import org.jgroups.Channel; +import org.jgroups.MembershipListener; +import org.jgroups.Message; +import org.jgroups.View; +import org.jgroups.blocks.MessageDispatcher; +import org.jgroups.blocks.RequestHandler; +import org.jgroups.conf.ConfiguratorFactory; +import org.jgroups.conf.ProtocolStackConfigurator; +import org.jgroups.util.Rsp; +import org.jgroups.util.RspList; +import org.picocontainer.Startable; + +import java.io.Externalizable; +import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectOutput; +import java.io.Serializable; +import java.net.URL; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Vector; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.CountDownLatch; + +/** + * This class is a basic implementation of the {@link RPCService}, it is mainly based on the + * {@link MessageDispatcher} of JGroups. This implementation is not designed to give + * the best possible performances, it only aims to give a way to communicate with other nodes. + * + * @author Nicolas Filotto + * @version $Id$ + */ +public abstract class AbstractRPCService implements RPCService, Startable, RequestHandler, MembershipListener +{ + + /** + * Connection logger. + */ + protected static final Log LOG = ExoLogger.getLogger("exo.kernel.component.common.RPCServiceImpl"); + + /** + * The name of the parameter for the location of the JGroups configuration. + */ + protected static final String PARAM_JGROUPS_CONFIG = "jgroups-configuration"; + + /** + * The name of the parameter for the name of the cluster. + */ + protected static final String PARAM_CLUSTER_NAME = "jgroups-cluster-name"; + + /** + * The name of the parameter for the default timeout + */ + protected static final String PARAM_DEFAULT_TIMEOUT = "jgroups-default-timeout"; + + /** + * The name of the parameter to allow the failover + */ + protected static final String PARAM_ALLOW_FAILOVER = "allow-failover"; + + /** + * The name of the parameter for the retry timeout + */ + protected static final String PARAM_RETRY_TIMEOUT = "retry-timeout"; + + /** + * The value of the default timeout + */ + protected static final int DEFAULT_TIMEOUT = 0; + + /** + * The value of the default retry timeout + */ + protected static final int DEFAULT_RETRY_TIMEOUT = 20000; + + /** + * The default value of the cluster name + */ + protected static final String CLUSTER_NAME = "RPCService-Cluster"; + + /** + * The configurator used to create the JGroups Channel + */ + protected final ProtocolStackConfigurator configurator; + + /** + * The lock used to synchronize all the threads waiting for a topology change. + */ + private final Object topologyChangeLock = new Object(); + + /** + * The name of the cluster + */ + private final String clusterName; + + /** + * The JGroups Channel used to communicate with other nodes + */ + protected Channel channel; + + /** + * The current list of all the members of the cluster + */ + protected volatile List
members; + + /** + * The address of the current coordinator + */ + protected volatile Address coordinator; + + /** + * Indicates whether the current node is the coordinator of the cluster or not + */ + protected volatile boolean isCoordinator; + + /** + * The default value of the timeout + */ + private long defaultTimeout = DEFAULT_TIMEOUT; + + /** + * The value of the retry timeout + */ + private long retryTimeout = DEFAULT_RETRY_TIMEOUT; + + /** + * Indicates whether the failover capabilities are enabled + */ + private boolean allowFailover = true; + + /** + * The dispatcher used to launch the command of the cluster nodes + */ + protected MessageDispatcher dispatcher; + + /** + * The signal that indicates that the service is started, it will be used + * to make the application wait until the service is fully started to + * ensure that all the commands have been registered before handling + * incoming messages. + */ + private final CountDownLatch startSignal = new CountDownLatch(1); + + /** + * All the registered {@link TopologyChangeListener} + */ + private final List listeners = new CopyOnWriteArrayList(); + + /** + * Current State of the {@link org.exoplatform.services.rpc.jgv3.RPCServiceImpl} + */ + private volatile State state; + + /** + * All the commands that have been registered + */ + private volatile Map commands = + Collections.unmodifiableMap(new HashMap()); + + /** + * The public constructor + * @param ctx the {@link ExoContainerContext} from which we will extract the corresponding + * {@link ExoContainer} + * @param params the list of initial parameters + * @param configManager the configuration manager used to get the configuration + * of JGroups + */ + public AbstractRPCService(ExoContainerContext ctx, InitParams params, ConfigurationManager configManager) + { + if (params == null) + { + throw new IllegalArgumentException("The RPCServiceImpl requires some parameters"); + } + final URL properties = getProperties(params, configManager); + if (LOG.isInfoEnabled()) + { + LOG.info("The JGroups configuration used for the RPCServiceImpl will be loaded from " + properties); + } + + try + { + this.configurator = ConfiguratorFactory.getStackConfigurator(properties); + } + catch (Exception e) + { + throw new RuntimeException("Cannot load the JGroups configuration from " + properties, e.getCause()); + } + + this.clusterName = getClusterName(ctx, params); + if (LOG.isDebugEnabled()) + { + LOG.debug("The cluster name of the RPCServiceImpl has been set to " + clusterName); + } + String sTimeout = getValueParam(params, PARAM_DEFAULT_TIMEOUT); + if (sTimeout != null) + { + defaultTimeout = Integer.parseInt(sTimeout); + if (LOG.isDebugEnabled()) + { + LOG.debug("The default timeout of the RPCServiceImpl has been set to " + defaultTimeout); + } + } + String sAllowFailover = getValueParam(params, PARAM_ALLOW_FAILOVER); + if (sAllowFailover != null) + { + allowFailover = Boolean.valueOf(sAllowFailover); + if (LOG.isDebugEnabled()) + { + LOG.debug("The parameter '" + PARAM_ALLOW_FAILOVER + "' of the RPCServiceImpl has been set to " + allowFailover); + } + } + sTimeout = getValueParam(params, PARAM_RETRY_TIMEOUT); + if (sTimeout != null) + { + retryTimeout = Integer.parseInt(sTimeout); + if (LOG.isDebugEnabled()) + { + LOG.debug("The retry timeout of the RPCServiceImpl has been set to " + retryTimeout); + } + } + this.state = State.INITIALIZED; + } + + /** + * {@inheritDoc} + */ + public List executeCommandOnAllNodes(RemoteCommand command, boolean synchronous, Serializable... args) + throws RPCException + { + return executeCommandOnAllNodesMain(command, synchronous, defaultTimeout, args); + } + + /** + * {@inheritDoc} + */ + public List executeCommandOnAllNodes(RemoteCommand command, long timeout, Serializable... args) + throws RPCException + { + return executeCommandOnAllNodesMain(command, true, timeout, args); + } + + /** + * Executes a command on all the cluster nodes. This method is equivalent to the other method of the + * same type but with the default timeout. The command must be registered first otherwise an + * {@link RPCException} will be thrown. + * + * @param command The command to execute on each cluster node + * @param synchronous if true, sets group request mode to org.jgroups.blocks.GroupRequest#GET_ALL, + * and if false sets it to org.jgroups.blocks.GroupRequest#GET_NONE. + * @param timeout a timeout after which to throw a replication exception. + * @param args an array of {@link Serializable} objects corresponding to parameters of the command + * to execute remotely + * @return a list of responses from all the members of the cluster. If we met an exception on a given node, + * the RPCException will be the corresponding response of this particular node + * @throws RPCException in the event of problems. + */ + protected List executeCommandOnAllNodesMain(RemoteCommand command, boolean synchronous, long timeout, + Serializable... args) throws RPCException + { + return excecuteCommand(members, command, synchronous, timeout, args); + } + + /** + * {@inheritDoc} + */ + public Object executeCommandOnCoordinator(RemoteCommand command, boolean synchronous, Serializable... args) + throws RPCException + { + return executeCommandOnCoordinatorMain(command, synchronous, defaultTimeout, args); + } + + /** + * {@inheritDoc} + */ + public Object executeCommandOnCoordinator(RemoteCommand command, long timeout, Serializable... args) + throws RPCException + { + return executeCommandOnCoordinatorMain(command, true, timeout, args); + } + + /** + * Executes a command on the coordinator only. This method is equivalent to the other method of the + * same type but with the default timeout. The command must be registered first otherwise an + * {@link RPCException} will be thrown. + * + * @param command The command to execute on the coordinator node + * @param synchronous if true, sets group request mode to org.jgroups.blocks.GroupRequest#GET_ALL, + * and if false sets it to org.jgroups.blocks.GroupRequest#GET_NONE. + * @param timeout a timeout after which to throw a replication exception. + * @param args an array of {@link Serializable} objects corresponding to parameters of the command + * to execute remotely + * @return the response of the coordinator. + * @throws RPCException in the event of problems. + */ + protected Object executeCommandOnCoordinatorMain(RemoteCommand command, boolean synchronous, long timeout, + Serializable... args) throws RPCException + { + Address coordinator = this.coordinator; + Vector
v = new Vector
(1); + v.add(coordinator); + List lResults = excecuteCommand(v, command, synchronous, timeout, args); + Object result = lResults == null || lResults.size() == 0 ? null : lResults.get(0); + if (allowFailover && result instanceof MemberHasLeftException) + { + // The failover capabilities have been enabled and the coordinator seems to have left + if (coordinator.equals(this.coordinator)) + { + synchronized(topologyChangeLock) + { + if (coordinator.equals(this.coordinator)) + { + if (LOG.isTraceEnabled()) + LOG.trace("The coordinator did not change yet, we will relaunch the command after " + + retryTimeout + " ms or once a topology change has been detected"); + try + { + topologyChangeLock.wait(retryTimeout); + } + catch (InterruptedException e) + { + Thread.currentThread().interrupt(); + } + } + } + } + if (LOG.isTraceEnabled()) + LOG.trace("The coordinator has changed, we will automatically retry with the new coordinator"); + return executeCommandOnCoordinator(command, synchronous, timeout, args); + } + else if (result instanceof RPCException) + { + throw (RPCException)result; + } + return result; + } + + /** + * Execute the command on all the nodes corresponding to the list of destinations. + * @param dests the list of members on which the command needs to be executed + * @param command the command to execute + * @param synchronous if true, sets group request mode to org.jgroups.blocks.GroupRequest#GET_ALL, and if false sets + * it to org.jgroups.blocks.GroupRequest#GET_NONE. + * @param timeout a timeout after which to throw a replication exception. + * @param args the list of parameters + * @return a list of responses from all the targeted members of the cluster. + * @throws RPCException in the event of problems. + */ + protected List excecuteCommand(final List
dests, RemoteCommand command, + final boolean synchronous, final long timeout, Serializable... args) throws RPCException + { + if (state != State.STARTED) + { + throw new RPCException( + "Cannot execute any commands if the service is not started, the current state of the service is " + state); + } + final String commandId = command.getId(); + if (commands.get(commandId) != command) + { + throw new RPCException("Command " + commandId + " unknown, please register your command first"); + } + final Message msg = new Message(); + setObject(msg, new MessageBody(dests.size() == 1 && dests != members ? dests.get(0) : null, commandId, args)); //NOSONAR + RspList rsps = null; + try + { + rsps = castMessage(dests, msg, synchronous, timeout); + } + catch (Exception e) + { + LOG.error("Could not cast the message corresponding to the command " + commandId + ".", e); + } + + if (LOG.isTraceEnabled()) + LOG.trace("responses: " + rsps); + if (rsps == null) + throw new RPCException("Could not get the responses for command " + commandId + "."); + if (!synchronous) + return Collections.emptyList();// async case + if (LOG.isTraceEnabled()) + { + LOG.trace("(" + getLocalAddress() + "): responses for command " + commandId + ":\n" + rsps); + } + List retval = new ArrayList(rsps.size()); + for (Address dest : dests) + { + Rsp rsp = rsps.get(dest); + if (rsp == null || (rsp.wasSuspected() && !rsp.wasReceived())) + { + // The corresponding member has left + retval.add(new MemberHasLeftException("No response for the member " + dest + + ", this member has probably left the cluster.")); + } + else if (!rsp.wasReceived()) + { + retval.add(new RPCException("Replication timeout for " + rsp.getSender() + ", rsp=" + rsp)); + } + else + { + Object value = rsp.getValue(); + if (value instanceof RPCException) + { + // if we have any application-level exceptions make sure we throw them!! + if (LOG.isTraceEnabled()) + LOG.trace("Recieved exception'" + value + "' from " + rsp.getSender(), (RPCException)value); + } + retval.add(value); + } + } + return retval; + } + + /** + * {@inheritDoc} + */ + public Object handle(Message msg) + { + String commandId = null; + try + { + // Ensure that the service is fully started before trying to execute any command + startSignal.await(); + MessageBody body = (MessageBody)msg.getObject(); + commandId = body.getCommandId(); + if (!body.accept(getLocalAddress())) + { + if (LOG.isTraceEnabled()) + { + LOG.trace("Command : " + commandId + " needs to be executed on the coordinator " + + "only and the local node is not the coordinator, the command will be ignored"); + } + return null; + } + RemoteCommand command = getCommand(commandId); + if (command == null) + { + return new RPCException("Command " + commandId + " unkown, please register your command first"); + } + Object execResult = command.execute(body.getArgs()); + if (LOG.isTraceEnabled()) + { + LOG.trace("Command : " + commandId + " executed, result is: " + execResult); + } + return execResult; + } + catch (Throwable x) //NOSONAR + { + if (LOG.isTraceEnabled()) + { + LOG.trace("Problems invoking command.", x); + } + return new RPCException("Cannot execute the command " + (commandId == null ? "" : commandId), x); + } + } + + /** + * {@inheritDoc} + */ + public void block() + { + } + + /** + * {@inheritDoc} + */ + public void suspect(Address suspectedMbr) + { + } + + /** + * {@inheritDoc} + */ + public void viewAccepted(View view) + { + boolean coordinatorHasChanged; + synchronized (topologyChangeLock) + { + this.members = getMembers(view); + Address currentCoordinator = coordinator; + this.coordinator = members != null && members.size() > 0 ? members.get(0) : null; + this.isCoordinator = coordinator != null && coordinator.equals(getLocalAddress()); + coordinatorHasChanged = currentCoordinator != null && !currentCoordinator.equals(coordinator); + // Release all the nodes + topologyChangeLock.notifyAll(); + } + onTopologyChange(coordinatorHasChanged); + } + + /** + * Called anytime the topology has changed, this method will notify all the listeners + * currently registered + * @param coordinatorHasChanged this parameter is set to true if the + * coordinator has changed, false otherwise + */ + private void onTopologyChange(boolean coordinatorHasChanged) + { + TopologyChangeEvent event = new TopologyChangeEvent(coordinatorHasChanged, isCoordinator); + for (TopologyChangeListener listener : listeners) + { + try + { + listener.onChange(event); + } + catch (Exception e) + { + LOG.warn("An error occurs with the listener of type " + listener.getClass(), e); + } + } + } + + /** + * {@inheritDoc} + */ + public synchronized RemoteCommand registerCommand(RemoteCommand command) + { + if (command != null) + { + String commandId = command.getId(); + if (commandId == null) + { + throw new IllegalArgumentException("The command Id cannot be null"); + } + Map tmpCommands = new HashMap(this.commands); + RemoteCommand oldCommand = tmpCommands.put(commandId, command); + if (oldCommand != null && PropertyManager.isDevelopping()) + { + LOG.warn("A command has already been registered with the id " + commandId + + ", this command will be replaced with the new one"); + } + this.commands = Collections.unmodifiableMap(tmpCommands); + return command; + } + return null; + } + + /** + * {@inheritDoc} + */ + public synchronized void unregisterCommand(RemoteCommand command) + { + if (command != null) + { + String commandId = command.getId(); + if (commandId == null) + { + throw new IllegalArgumentException("The command Id cannot be null"); + } + if (commands.get(commandId) != command) + { + // We prevent to remove any command that has not been registered, thus we expect that + // the registered instance is exactly the same instance as the one that we want to + // unregister + if (PropertyManager.isDevelopping()) + { + LOG.warn("Cannot unregister an unknown RemoteCommand, either the command id " + commandId + + " is unknown or the instance of RemoteCommand to unregister is unknown"); + } + return; + } + Map tmpCommands = new HashMap(this.commands); + tmpCommands.remove(commandId); + this.commands = Collections.unmodifiableMap(tmpCommands); + } + } + + /** + * {@inheritDoc} + */ + public boolean isCoordinator() throws RPCException + { + if (state != State.STARTED) + { + throw new RPCException("Cannot know whether the local node is a coordinator or not if " + + "the service is not started, the current state of the service is " + state); + } + return isCoordinator; + } + + /** + * {@inheritDoc} + */ + public void registerTopologyChangeListener(TopologyChangeListener listener) throws SecurityException + { + if (listener == null) + { + return; + } + listeners.add(listener); + } + + /** + * {@inheritDoc} + */ + public void unregisterTopologyChangeListener(TopologyChangeListener listener) throws SecurityException + { + if (listener == null) + { + return; + } + listeners.remove(listener); + } + + /** + * Gives the {@link RemoteCommand} corresponding to the given id + * @param commandId the command id of the command to retrieve + * @return the corresponding {@link RemoteCommand} + */ + protected RemoteCommand getCommand(String commandId) + { + return commands.get(commandId); + } + + /** + * {@inheritDoc} + */ + public void start() + { + try + { + channel = createChannel(); + dispatcher = new MessageDispatcher(channel, null, AbstractRPCService.this, AbstractRPCService.this); + channel.connect(clusterName); + } + catch (Exception e) + { + throw new RuntimeException("Cannot initialize the Channel needed for the RPCServiceImpl", e.getCause()); + } + finally + { + this.state = State.STARTED; + startSignal.countDown(); + } + } + + /** + * {@inheritDoc} + */ + public void stop() + { + this.state = State.STOPPED; + this.isCoordinator = false; + if (channel != null && channel.isOpen()) + { + if (LOG.isInfoEnabled()) + LOG.info("Disconnecting and closing the Channel"); + channel.disconnect(); + channel.close(); + channel = null; + } + if (dispatcher != null) + { + dispatcher.stop(); + dispatcher = null; + } + } + + /** + * Gives the value of the default timeout + * @return the default timeout + */ + protected long getDefaultTimeout() + { + return defaultTimeout; + } + + /** + * Gives the name of the cluster + * @return the name of the cluster + */ + protected String getClusterName() + { + return clusterName; + } + + /** + * Gives the value of the retry timeout + * @return the value of the retry timeout + */ + protected long getRetryTimeout() + { + return retryTimeout; + } + + /** + * Indicates whether the failover capabilities are enabled or not + * @return true if the failover capabilities are allowed, false + * otherwise + */ + protected boolean isAllowFailover() + { + return allowFailover; + } + + /** + * Returns the channel's own address. The result of calling this method on an unconnected + * channel is implementation defined (may return null). Calling this method on a closed + * channel returns null. Successor to #getAddress(). Addresses can be used as destination + * in the send() operation. + * @return The channel's address (opaque) or null if it cannot be found + */ + protected abstract Address getLocalAddress(); + + /** + * Returns the IP address of current channel. + * @return The Host's address or null if it cannot be found + */ + public abstract String getHostAddress(); + + /** + * Cast a message to all the given members + * @param dests The members to which the message is to be sent. + * @param msg The message to be sent to the members. + * @param synchronous Indicates whether the message must be sent in synchronous or asynchronous mode. + * @param timeout If 0: wait forever. Otherwise, wait for responses or timeout time. + * @return A list of responses. Each response is an Object and associated to its sender. + * @throws Exception if any error occur while casting the message + */ + protected abstract RspList castMessage(List
dests, Message msg, boolean synchronous, long timeout) throws Exception; + + /** + * Create a channel + * @return An initialized channel + * @throws Exception if any error occur while creating the channel + */ + protected abstract Channel createChannel() throws Exception; + + /** + * Returns a reference to the List of members (ordered) + * Do NOT change this list, hence your will invalidate the view + * Make a copy if you have to modify it. + * + * @return a reference to the ordered list of members in this view + */ + protected abstract List
getMembers(View view); + + /** + * Takes an object and uses Java serialization to generate the byte[] buffer which + * is set in the message. + */ + protected abstract void setObject(Message m, Object o); + + /** + * Gives the value of the {@link ValueParam} corresponding to the given key + * @param params the list of initial parameters from which we want to extract the {@link ValueParam} + * @param parameterKey the name of the {@link ValueParam} that we are looking for + * @return the value if it exists, null otherwise + */ + private static String getValueParam(InitParams params, String parameterKey) + { + if (params != null) + { + ValueParam parameterKeyValue = params.getValueParam(parameterKey); + if (parameterKeyValue != null) + { + String parameterKeyValueString = parameterKeyValue.getValue(); + if (parameterKeyValueString != null) + { + return parameterKeyValueString.trim(); + } + } + } + return null; + } + + /** + * Gives the {@link URL} corresponding to the location of the JGroups configuration + * @param params the initial parameters from which we extract the parameter + * PARAM_JGROUPS_CONFIG + * @param configManager the configuration manager used to get the {@link URL} corresponding + * to the path given in the configuration of the RPCServiceImpl + * @return The {@link URL} corresponding to the location of the JGroups configuration, + * it will throw {@link RuntimeException} otherwise since it is a mandatory configuration. + */ + private static URL getProperties(InitParams params, ConfigurationManager configManager) + { + String configPath = getValueParam(params, PARAM_JGROUPS_CONFIG); + if (configPath == null) + { + throw new IllegalArgumentException("The parameter '" + PARAM_JGROUPS_CONFIG + + "' of RPCServiceImpl is mandatory"); + } + URL properties; + try + { + properties = configManager.getResource(configPath); + } + catch (Exception e) + { + throw new IllegalArgumentException("Cannot find the JGroups configuration at " + configPath, e); + } + if (properties == null) + { + throw new IllegalArgumentException("Cannot find the JGroups configuration at " + configPath); + } + return properties; + } + + /** + * Gives the name of the cluster that will be able to support several portal containers + * since the name will be post fixed with "-${container-name}" + * @param ctx the context from which we extract the name of the container + * @param params the list of initial parameters from which we get the value of the parameter + * PARAM_CLUSTER_NAME if it exists otherwise the value will be "RPCService-Cluster" + */ + private static String getClusterName(ExoContainerContext ctx, InitParams params) + { + String clusterName = getValueParam(params, PARAM_CLUSTER_NAME); + if (clusterName == null) + { + clusterName = CLUSTER_NAME; + } + return clusterName += "-" + ctx.getName(); + } + + /** + * This intern class will be used to + */ + public static class MessageBody implements Externalizable + { + /** + * The Id of the command to execute + */ + private String commandId; + + /** + * The list of parameters + */ + private Serializable[] args; + + /** + * The hash code of the expected destination + */ + private int destination; + + public MessageBody() + { + } + + /** + * @param dest The destination of the message + * @param commandId the id of the command to execute + * @param args the arguments to use + */ + public MessageBody(Address dest, String commandId, Serializable[] args) + { + this.commandId = commandId; + this.args = args; + this.destination = dest == null ? 0 : dest.hashCode(); + } + + public String getCommandId() + { + return commandId; + } + + public Serializable[] getArgs() + { + return args; + } + + /** + * Indicates whether or not the given message body accepts the given address + * @param address the address to check + * @return true if the message is for everybody or if the given address is the expected address, + * false otherwise + */ + public boolean accept(Address address) + { + return destination == 0 || destination == address.hashCode(); + } + + /** + * {@inheritDoc} + */ + public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException + { + boolean unicast = in.readBoolean(); + if (unicast) + { + this.destination = in.readInt(); + } + this.commandId = in.readUTF(); + int size = in.readInt(); + if (size == -1) + { + this.args = null; + } + else + { + this.args = new Serializable[size]; + for (int i = 0; i < size; i++) + { + args[i] = (Serializable)in.readObject(); + } + } + } + + /** + * {@inheritDoc} + */ + public void writeExternal(ObjectOutput out) throws IOException + { + boolean unicast = destination != 0; + out.writeBoolean(unicast); + if (unicast) + { + out.writeInt(destination); + } + out.writeUTF(commandId); + if (args == null) + { + out.writeInt(-1); + } + else + { + out.writeInt(args.length); + for (int i = 0; i < args.length; i++) + { + out.writeObject(args[i]); + } + } + } + } + + /** + * All the potential states of the {@link org.exoplatform.services.rpc.jgv3.RPCServiceImpl} + */ + public enum State + { + INITIALIZED, STARTED, STOPPED + } + + public static class MemberHasLeftException extends RPCException + { + + /** + * The serial version UID + */ + private static final long serialVersionUID = 3558158913564367637L; + + public MemberHasLeftException(String message) + { + super(message); + } + } +} diff --git a/exo.jcr.component.core/src/main/java/org/exoplatform/services/rpc/jgv3/RPCServiceImpl.java b/exo.jcr.component.core/src/main/java/org/exoplatform/services/rpc/jgv3/RPCServiceImpl.java new file mode 100644 index 0000000000..16d5a17686 --- /dev/null +++ b/exo.jcr.component.core/src/main/java/org/exoplatform/services/rpc/jgv3/RPCServiceImpl.java @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2010 eXo Platform SAS. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.exoplatform.services.rpc.jgv3; + +import org.exoplatform.container.ExoContainerContext; +import org.exoplatform.container.configuration.ConfigurationManager; +import org.exoplatform.container.xml.InitParams; +import org.exoplatform.services.rpc.impl.AbstractRPCService; +import org.jgroups.*; +import org.jgroups.blocks.RequestOptions; +import org.jgroups.blocks.ResponseMode; +import org.jgroups.stack.IpAddress; +import org.jgroups.util.RspList; + +import java.util.List; + +/** + * This class is the implementation of the {@link AbstractRPCService} for JGroups 3. + * + * @author Nicolas Filotto + * @version $Id$ + */ +public class RPCServiceImpl extends AbstractRPCService +{ + + /** + * {@inheritDoc} + */ + public RPCServiceImpl(ExoContainerContext ctx, InitParams params, ConfigurationManager configManager) + { + super(ctx, params, configManager); + } + + /** + * {@inheritDoc} + */ + protected Address getLocalAddress() + { + return channel.getAddress(); + } + + /** + * {@inheritDoc} + */ + public String getHostAddress() + { + String address = null; + org.jgroups.Address jgAddress = channel.getAddress() ; + if (!(jgAddress instanceof IpAddress)) + { + // this is the only way of getting physical address. + jgAddress = (org.jgroups.Address)channel.down(new Event(Event.GET_PHYSICAL_ADDRESS, jgAddress)); + } + if (jgAddress instanceof IpAddress) + { + address = ((IpAddress)jgAddress).getIpAddress().getHostAddress(); + } + else + { + LOG.error("Unsupported Address object : " + jgAddress.getClass().getName()); + } + return address; + } + + /** + * {@inheritDoc} + */ + protected RspList castMessage(List
dests, Message msg, boolean synchronous, long timeout) throws Exception + { + return dispatcher.castMessage(dests, msg, new RequestOptions(synchronous ? ResponseMode.GET_ALL + : ResponseMode.GET_NONE, timeout)); + } + + /** + * {@inheritDoc} + */ + protected Channel createChannel() throws Exception + { + return new JChannel(configurator); + } + + /** + * {@inheritDoc} + */ + public void unblock() + { + } + + /** + * {@inheritDoc} + */ + protected List
getMembers(View view) + { + return view.getMembers(); + } + + /** + * {@inheritDoc} + */ + protected void setObject(Message m, Object o) + { + m.setObject(o); + } +} diff --git a/exo.jcr.component.core/src/main/java/org/exoplatform/services/transaction/ActionNonTxAware.java b/exo.jcr.component.core/src/main/java/org/exoplatform/services/transaction/ActionNonTxAware.java new file mode 100644 index 0000000000..4b535b81c6 --- /dev/null +++ b/exo.jcr.component.core/src/main/java/org/exoplatform/services/transaction/ActionNonTxAware.java @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2011 eXo Platform SAS. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.exoplatform.services.transaction; + +import org.exoplatform.services.log.ExoLogger; +import org.exoplatform.services.log.Log; + +import javax.transaction.SystemException; +import javax.transaction.Transaction; +import javax.transaction.TransactionManager; + +/** + * This class describes all the actions that are not supposed to be called + * within a transaction + * + * @author Nicolas Filotto + * @version $Id$ + * + */ +public abstract class ActionNonTxAware +{ + /** + * The logger + */ + protected static final Log LOG = ExoLogger.getLogger(ActionNonTxAware.class); + + /** + * Executes the action outside the context of the current tx + * @param arg the argument to use to execute the action + * @return the result of the action + * @throws E if an error occurs while executing the action + */ + public R run(A... arg) throws E + { + final TransactionManager tm = getTransactionManager(); + Transaction tx = null; + try + { + if (tm != null) + { + try + { + tx = tm.suspend(); + } + catch (SystemException e) + { + LOG.warn("Cannot suspend the current transaction", e); + } + } + return execute(arg); + } + finally + { + if (tx != null) + { + try + { + tm.resume(tx); + } + catch (Exception e) + { + LOG.warn("Cannot resume the current transaction", e); + } + } + } + } + + /** + * Executes the action outside the context of the current tx. This + * method is equivalent to {@link ActionNonTxAware#run(Object[])}} but + * with null as parameter. + * @return the result of the action + * @throws E if an error occurs while executing the action + */ + public R run() throws E + { + return run((A[])null); + } + + /** + * Executes the action + * @param arg the argument to use to execute the action + * @return the result of the action + * @throws E if an error occurs while executing the action + */ + protected R execute(A... arg) throws E + { + if (arg == null || arg.length == 0) + { + return execute((A)null); + } + return execute(arg[0]); + } + + /** + * Executes the action + * @param arg the argument to use to execute the action + * @return the result of the action + * @throws E if an error occurs while executing the action + */ + protected R execute(A arg) throws E + { + return null; + } + + /** + * Gives the Transaction Manager that will be used while executing the action + * @return the {@link TransactionManager} to use + */ + protected abstract TransactionManager getTransactionManager(); +} diff --git a/exo.jcr.component.ext/pom.xml b/exo.jcr.component.ext/pom.xml index d42de5b1a7..2a17b712fc 100644 --- a/exo.jcr.component.ext/pom.xml +++ b/exo.jcr.component.ext/pom.xml @@ -57,10 +57,7 @@ org.codehaus.groovy groovy-all - true - - io.meeds.kernel exo.kernel.commons.test diff --git a/exo.jcr.component.ext/src/main/java/org/exoplatform/services/rest/ext/groovy/BaseResourceId.java b/exo.jcr.component.ext/src/main/java/org/exoplatform/services/rest/ext/groovy/BaseResourceId.java new file mode 100644 index 0000000000..68a3904072 --- /dev/null +++ b/exo.jcr.component.ext/src/main/java/org/exoplatform/services/rest/ext/groovy/BaseResourceId.java @@ -0,0 +1,73 @@ +/* + * This file is part of the Meeds project (https://meeds.io/). + * Copyright (C) 2020 Meeds Association + * contact@meeds.io + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser 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 + * Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package org.exoplatform.services.rest.ext.groovy; + +/** + * Base implementation of ResourceId. + * + * @author Andrey Parfonov + * @version $Id$ + */ +public class BaseResourceId implements ResourceId +{ + + protected final String id; + + public BaseResourceId(String id) + { + this.id = id; + } + + /** + * {@inheritDoc} + */ + public String getId() + { + return id; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean equals(Object obj) + { + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + return id.equals(((BaseResourceId)obj).id); + } + + /** + * {@inheritDoc} + */ + @Override + public int hashCode() + { + return id.hashCode(); + } + + /** + * {@inheritDoc} + */ + public String toString() + { + return getClass().getSimpleName() + '(' + id + ')'; + } +} diff --git a/exo.jcr.component.ext/src/main/java/org/exoplatform/services/rest/ext/groovy/ClassPathEntry.java b/exo.jcr.component.ext/src/main/java/org/exoplatform/services/rest/ext/groovy/ClassPathEntry.java new file mode 100644 index 0000000000..941462b3cd --- /dev/null +++ b/exo.jcr.component.ext/src/main/java/org/exoplatform/services/rest/ext/groovy/ClassPathEntry.java @@ -0,0 +1,40 @@ +/* + * This file is part of the Meeds project (https://meeds.io/). + * Copyright (C) 2020 Meeds Association + * contact@meeds.io + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser 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 + * Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.exoplatform.services.rest.ext.groovy; + +import java.net.URL; + +/** + * Item of Groovy classpath. + * + * @author Andrey Parfonov + * @version $Id$ + */ +public abstract class ClassPathEntry +{ + private final URL path; + + public ClassPathEntry(URL path) + { + this.path = path; + } + + public URL getPath() + { + return path; + } +} diff --git a/exo.jcr.component.ext/src/main/java/org/exoplatform/services/rest/ext/groovy/DefaultGroovyResourceLoader.java b/exo.jcr.component.ext/src/main/java/org/exoplatform/services/rest/ext/groovy/DefaultGroovyResourceLoader.java new file mode 100644 index 0000000000..2c59fcba64 --- /dev/null +++ b/exo.jcr.component.ext/src/main/java/org/exoplatform/services/rest/ext/groovy/DefaultGroovyResourceLoader.java @@ -0,0 +1,193 @@ +/* + * This file is part of the Meeds project (https://meeds.io/). + * Copyright (C) 2020 Meeds Association + * contact@meeds.io + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser 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 + * Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package org.exoplatform.services.rest.ext.groovy; + +import groovy.lang.GroovyResourceLoader; + +import org.exoplatform.services.log.ExoLogger; +import org.exoplatform.services.log.Log; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.concurrent.Callable; +import java.util.concurrent.CancellationException; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import java.util.concurrent.FutureTask; + +/** + * @author Andrey Parfonov + * @version $Id: DefaultGroovyResourceLoader.java 2680 2010-06-22 11:43:00Z + * aparfonov $ + */ +public class DefaultGroovyResourceLoader implements GroovyResourceLoader +{ + private static final String DEFAULT_SOURCE_FILE_EXTENSION = ".groovy"; + + private static final Log LOG = ExoLogger.getLogger("exo.ws.rest.ext.DefaultGroovyResourceLoader"); + + public final ConcurrentMap> findResourceURLTasks = new ConcurrentHashMap>(); + + private int maxEntries = 512; + + protected final Map resources; + + protected final URL[] roots; + + @SuppressWarnings("serial") + public DefaultGroovyResourceLoader(URL[] roots) throws MalformedURLException + { + this.roots = new URL[roots.length]; + for (int i = 0; i < roots.length; i++) + { + String str = roots[i].toString(); + if (str.charAt(str.length() - 1) != '/') + this.roots[i] = new URL(str + '/'); + else + this.roots[i] = roots[i]; + } + resources = Collections.synchronizedMap(new LinkedHashMap() + { + protected boolean removeEldestEntry(Entry eldest) + { + return size() > maxEntries; + } + }); + } + + public DefaultGroovyResourceLoader(URL root) throws MalformedURLException + { + this(new URL[]{root}); + } + + /** + * {@inheritDoc} + */ + public final URL loadGroovySource(String filename) throws MalformedURLException + { + URL resource = null; + final String ffilename = filename.replace('.', '/') + getSourceFileExtension(); + return getResource(ffilename); + } + + protected URL getResource(final String filename) throws MalformedURLException + { + // First we check the cache outside the synchronized block + URL resource = resources.get(filename); + if (resource != null && checkResource(resource)) + { + // The resource could be found in the cache and is reachable + return resource; + } + // The resource cannot be found or is unreachable + // Check if a corresponding findResourceURL task exists + Future findResourceURLTask = findResourceURLTasks.get(filename); + if (findResourceURLTask == null) + { + // The task doesn't exist so we create it + FutureTask f = new FutureTask(new Callable() + { + public URL call() throws Exception + { + return findResourceURL(filename); + } + }); + // We add the new task to the existing tasks + findResourceURLTask = findResourceURLTasks.putIfAbsent(filename, f); + if (findResourceURLTask == null) + { + // The task has not be registered so we launch it + findResourceURLTask = f; + f.run(); + } + } + try + { + return findResourceURLTask.get(); + } + catch (CancellationException e) + { + if (LOG.isTraceEnabled()) + { + LOG.trace("An exception occurred: " + e.getMessage()); + } + } + catch (ExecutionException e) + { + throw (MalformedURLException)e.getCause(); + } + catch (InterruptedException e) + { + Thread.currentThread().interrupt(); + } + finally + { + findResourceURLTasks.remove(filename, findResourceURLTask); + } + return null; + } + + protected URL findResourceURL(String filename) throws MalformedURLException + { + URL resource = resources.get(filename); + boolean inCache = resource != null; + if (inCache && !checkResource(resource)) + resource = null; // Resource in cache is unreachable. + for (int i = 0; i < roots.length && resource == null; i++) + { + URL tmp = createURL(roots[i], filename); + if (checkResource(tmp)) + resource = tmp; + } + if (resource != null) + resources.put(filename, resource); + else if (inCache) + resources.remove(filename); + return resource; + } + + protected URL createURL(URL root, String filename) throws MalformedURLException + { + return new URL(root, filename); + } + + protected String getSourceFileExtension() + { + return DEFAULT_SOURCE_FILE_EXTENSION; + } + + protected boolean checkResource(URL resource) + { + try + { + resource.openStream().close(); + return true; + } + catch (IOException e) + { + return false; + } + } +} diff --git a/exo.jcr.component.ext/src/main/java/org/exoplatform/services/rest/ext/groovy/ExtendedGroovyClassLoader.java b/exo.jcr.component.ext/src/main/java/org/exoplatform/services/rest/ext/groovy/ExtendedGroovyClassLoader.java new file mode 100644 index 0000000000..fed11f3010 --- /dev/null +++ b/exo.jcr.component.ext/src/main/java/org/exoplatform/services/rest/ext/groovy/ExtendedGroovyClassLoader.java @@ -0,0 +1,300 @@ +/* + * This file is part of the Meeds project (https://meeds.io/). + * Copyright (C) 2020 Meeds Association + * contact@meeds.io + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser 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 + * Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.exoplatform.services.rest.ext.groovy; + +import groovy.lang.GroovyClassLoader; + +import org.codehaus.groovy.ast.ClassNode; +import org.codehaus.groovy.ast.ModuleNode; +import org.codehaus.groovy.control.CompilationFailedException; +import org.codehaus.groovy.control.CompilationUnit; +import org.codehaus.groovy.control.CompilerConfiguration; +import org.codehaus.groovy.control.Phases; +import org.codehaus.groovy.control.SourceUnit; + +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.security.CodeSource; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +/** + * @author Andrey Parfonov + * @version $Id: ExtendedGroovyClassLoader.java 3731 2010-12-27 13:35:46Z + * aparfonov $ + */ +@SuppressWarnings({"rawtypes", "unchecked"}) +public class ExtendedGroovyClassLoader extends GroovyClassLoader +{ + public static final String CODE_BASE = "/groovy/script/jaxrs"; + + public static class SingleClassCollector extends GroovyClassLoader.ClassCollector + { + protected final CompilationUnit cunit; + protected final SourceUnit sunit; + protected Class target; + + protected SingleClassCollector(ExtendedInnerLoader cl, CompilationUnit cunit, SourceUnit sunit) + { + super(cl, cunit, sunit); + this.cunit = cunit; + this.sunit = sunit; + } + + @Override + protected Class createClass(byte[] code, ClassNode classNode) + { + ExtendedInnerLoader cl = (ExtendedInnerLoader)getDefiningClassLoader(); + /*String classname = classNode.getName(); + int i = classname.lastIndexOf('.'); + if (i != -1) + { + String pkgname = classname.substring(0, i); + cl.definePackage(pkgname); + }*/ + Class clazz = cl.defineClass(classNode.getName(), code, cunit.getAST().getCodeSource()); + getLoadedClasses().add(clazz); + if (target == null) + { + ClassNode targetClassNode = null; + SourceUnit targetSunit = null; + ModuleNode module = classNode.getModule(); + + if (module != null) + { + targetClassNode = (ClassNode)module.getClasses().get(0); + targetSunit = module.getContext(); + } + + if (targetSunit == sunit && targetClassNode == classNode) //NOSONAR + { + target = clazz; + } + } + return clazz; + } + + public Class getTarget() + { + return target; + } + } + + public static class MultipleClassCollector extends GroovyClassLoader.ClassCollector + { + protected final CompilationUnit cunit; + protected final Set sunitSet; + private final List compiledClasses; + + protected MultipleClassCollector(ExtendedInnerLoader cl, CompilationUnit cunit, Set sunitSet) + { + super(cl, cunit, null); + this.cunit = cunit; + this.sunitSet = sunitSet; + this.compiledClasses = new ArrayList(); + } + + @Override + protected Class createClass(byte[] code, ClassNode classNode) + { + ExtendedInnerLoader cl = (ExtendedInnerLoader)getDefiningClassLoader(); + /*String classname = classNode.getName(); + int i = classname.lastIndexOf('.'); + if (i != -1) + { + String pkgname = classname.substring(0, i); + cl.definePackage(pkgname); + }*/ + Class clazz = cl.defineClass(classNode.getName(), code, cunit.getAST().getCodeSource()); + getLoadedClasses().add(clazz); + ModuleNode module = classNode.getModule(); + if (module != null) + { + SourceUnit currentSunit = module.getContext(); + if (sunitSet.contains(currentSunit)) + compiledClasses.add(clazz); + } + return clazz; + } + + public List getCompiledClasses() + { + return compiledClasses; + } + } + + public static class ExtendedInnerLoader extends GroovyClassLoader.InnerLoader + { + public ExtendedInnerLoader(ExtendedGroovyClassLoader parent) + { + super(parent); + } + + protected Class defineClass(String name, byte[] code, CodeSource cs) + { + return super.defineClass(name, code, 0, code.length, cs); + } + + protected void definePackage(String name) throws IllegalArgumentException + { + Package pkg = getPackage(name); + if (pkg == null) + super.definePackage(name, null, null, null, null, null, null, null); + } + } + + public ExtendedGroovyClassLoader(ClassLoader classLoader) + { + super(classLoader); + } + + public ExtendedGroovyClassLoader(GroovyClassLoader parent) + { + super(parent); + } + + public Class parseClass(InputStream in, String fileName, SourceFile[] files) throws CompilationFailedException + { + return doParseClass(in, fileName, files, Phases.CLASS_GENERATION, null, false); + } + + protected Class doParseClass(InputStream in, String fileName, SourceFile[] files, int phase, + CompilerConfiguration config, boolean shouldCacheSource) throws CompilationFailedException + { + synchronized (sourceCache) + { + Class target = (Class)sourceCache.get(fileName); + if (target == null) + { + CodeSource cs = new CodeSource(getCodeSource(), (java.security.cert.Certificate[])null); + CompilationUnit cunit = createCompilationUnit(config, cs); + SourceUnit targetSunit = cunit.addSource(fileName, in); + if (files != null) + { + for (int i = 0; i < files.length; i++) + cunit.addSource(files[i].getPath()); + } + SingleClassCollector collector = createSingleCollector(cunit, targetSunit); + cunit.setClassgenCallback(collector); + cunit.compile(phase); + + for (Iterator iter = collector.getLoadedClasses().iterator(); iter.hasNext();) + { + Class clazz = (Class)iter.next(); + String classname = clazz.getName(); + int i = classname.lastIndexOf('.'); + if (i != -1) + { + String pkgname = classname.substring(0, i); + Package pkg = getPackage(pkgname); + if (pkg == null) + definePackage(pkgname, null, null, null, null, null, null, null); + } + setClassCacheEntry(clazz); + } + + target = collector.getTarget(); + + if (shouldCacheSource) + sourceCache.put(fileName, target); + } + + return target; + } + } + + public Class[] parseClasses(SourceFile[] files) + { + return doParseClasses(files, Phases.CLASS_GENERATION, null); + } + + protected Class[] doParseClasses(SourceFile[] sources, int phase, CompilerConfiguration config) + { + synchronized (classCache) + { + CodeSource cs = new CodeSource(getCodeSource(), (java.security.cert.Certificate[])null); + CompilationUnit cunit = createCompilationUnit(config, cs); + Set setSunit = new HashSet(); + for (int i = 0; i < sources.length; i++) + setSunit.add(cunit.addSource(sources[i].getPath())); + MultipleClassCollector collector = createMultipleCollector(cunit, setSunit); + cunit.setClassgenCallback(collector); + cunit.compile(phase); + + for (Iterator iter = collector.getLoadedClasses().iterator(); iter.hasNext();) + { + Class clazz = (Class)iter.next(); + String classname = clazz.getName(); + int i = classname.lastIndexOf('.'); + if (i != -1) + { + String pkgname = classname.substring(0, i); + Package pkg = getPackage(pkgname); + if (pkg == null) + definePackage(pkgname, null, null, null, null, null, null, null); + } + setClassCacheEntry(clazz); + } + List compiledClasses = collector.getCompiledClasses(); + return compiledClasses.toArray(new Class[compiledClasses.size()]); + } + } + + /** + * @see groovy.lang.GroovyClassLoader#createCompilationUnit(org.codehaus.groovy.control.CompilerConfiguration, + * java.security.CodeSource) + */ + @Override + protected CompilationUnit createCompilationUnit(CompilerConfiguration config, CodeSource cs) + { + return new CompilationUnit(config, cs, this); + } + + protected SingleClassCollector createSingleCollector(CompilationUnit unit, SourceUnit sunit) + { + ExtendedInnerLoader loader = new ExtendedInnerLoader(ExtendedGroovyClassLoader.this); + return new SingleClassCollector(loader, unit, sunit); + } + + protected MultipleClassCollector createMultipleCollector(CompilationUnit unit, Set setSunit) + { + ExtendedInnerLoader loader = new ExtendedInnerLoader(ExtendedGroovyClassLoader.this); + return new MultipleClassCollector(loader, unit, setSunit); + } + + protected URL getCodeSource() + { + return getCodeSource(CODE_BASE); + } + + private URL getCodeSource(String codeBase) + { + try + { + return new URL("file", "", codeBase); + } + catch (MalformedURLException e) + { + throw new IllegalArgumentException("Unable create code source URL from: " + codeBase + ". " + e.getMessage(), + e); + } + } +} diff --git a/exo.jcr.component.ext/src/main/java/org/exoplatform/services/rest/ext/groovy/GroovyClassLoaderProvider.java b/exo.jcr.component.ext/src/main/java/org/exoplatform/services/rest/ext/groovy/GroovyClassLoaderProvider.java new file mode 100644 index 0000000000..81ed0a3f16 --- /dev/null +++ b/exo.jcr.component.ext/src/main/java/org/exoplatform/services/rest/ext/groovy/GroovyClassLoaderProvider.java @@ -0,0 +1,82 @@ +/* + * This file is part of the Meeds project (https://meeds.io/). + * Copyright (C) 2020 Meeds Association + * contact@meeds.io + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser 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 + * Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.exoplatform.services.rest.ext.groovy; + +import groovy.lang.GroovyClassLoader; + + +import java.net.MalformedURLException; +import java.net.URL; + +/** + * Factory of Groovy class loader. It can provide preset GroovyClassLoader + * instance or customized instance of GroovyClassLoader able resolve additional + * Groovy source files. + * + * @author Andrey Parfonov + * @version $Id: GroovyClassLoaderProvider.java 3701 2010-12-22 10:15:37Z + * aparfonov $ + */ +public class GroovyClassLoaderProvider +{ + /** Preset default GroovyClassLoader. */ + private ExtendedGroovyClassLoader defaultClassLoader; + + public GroovyClassLoaderProvider() + { + this(new ExtendedGroovyClassLoader(GroovyClassLoaderProvider.class.getClassLoader())); + } + + protected GroovyClassLoaderProvider(ExtendedGroovyClassLoader defaultClassLoader) + { + this.defaultClassLoader = defaultClassLoader; + } + + /** + * Get default GroovyClassLoader. + * + * @return default GroovyClassLoader + */ + public ExtendedGroovyClassLoader getGroovyClassLoader() + { + return defaultClassLoader; + } + + /** + * Get customized instance of GroovyClassLoader that able to resolve + * additional Groovy source files. + * + * @param sources additional Groovy sources + * @return GroovyClassLoader + * @throws MalformedURLException if any of entries in sources + * has invalid URL. + */ + public ExtendedGroovyClassLoader getGroovyClassLoader(SourceFolder[] sources) throws MalformedURLException + { + if (sources == null || sources.length == 0) + return getGroovyClassLoader(); + + URL[] roots = new URL[sources.length]; + for (int i = 0; i < sources.length; i++) + roots[i] = sources[i].getPath(); + + final GroovyClassLoader parent = getGroovyClassLoader(); + ExtendedGroovyClassLoader classLoader = new ExtendedGroovyClassLoader(parent); + classLoader.setResourceLoader(new DefaultGroovyResourceLoader(roots)); + return classLoader; + } +} diff --git a/exo.jcr.component.ext/src/main/java/org/exoplatform/services/rest/ext/groovy/GroovyJaxrsPublisher.java b/exo.jcr.component.ext/src/main/java/org/exoplatform/services/rest/ext/groovy/GroovyJaxrsPublisher.java new file mode 100644 index 0000000000..59f8294f98 --- /dev/null +++ b/exo.jcr.component.ext/src/main/java/org/exoplatform/services/rest/ext/groovy/GroovyJaxrsPublisher.java @@ -0,0 +1,681 @@ +/* + * This file is part of the Meeds project (https://meeds.io/). + * Copyright (C) 2020 Meeds Association + * contact@meeds.io + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser 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 + * Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package org.exoplatform.services.rest.ext.groovy; + +import groovy.lang.GroovyClassLoader; +import groovy.lang.GroovyCodeSource; +import groovy.lang.GroovySystem; + +import org.codehaus.groovy.control.CompilationFailedException; +import org.exoplatform.container.ExoContainer; +import org.exoplatform.container.ExoContainerContext; +import org.exoplatform.services.log.ExoLogger; +import org.exoplatform.services.log.Log; +import org.exoplatform.services.rest.ObjectFactory; +import org.exoplatform.services.rest.PerRequestObjectFactory; +import org.exoplatform.services.rest.impl.ResourceBinder; +import org.exoplatform.services.rest.impl.ResourcePublicationException; +import org.exoplatform.services.rest.resource.AbstractResourceDescriptor; +import org.exoplatform.services.rest.uri.UriPattern; +import org.exoplatform.services.script.groovy.GroovyScriptInstantiator; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.net.MalformedURLException; +import java.net.URL; +import java.nio.charset.Charset; +import java.nio.charset.UnsupportedCharsetException; //NOSONAR +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.ws.rs.Path; +import javax.ws.rs.core.MultivaluedMap; + +/** + * Manage via {@link ResourceBinder} Groovy based RESTful services. + * + * @author Andrey Parfonov + * @version $Id$ + */ +public class GroovyJaxrsPublisher +{ + private static final Log LOG = ExoLogger.getExoLogger(GroovyJaxrsPublisher.class); + static + { + // We get the version of groovy as workaround, to make + // sure that it will be able to load the META-INF/dgminfo + String version = GroovySystem.getVersion(); + LOG.debug("The version of groovy used is {}", version); + } + + @SuppressWarnings("rawtypes") + private static final Comparator constructorComparator = new Comparator() { + public int compare(Constructor o1, Constructor o2) + { + int c1 = o1.getParameterTypes().length; + int c2 = o2.getParameterTypes().length; + if (c1 < c2) + return 1; + if (c1 > c2) + return -1; + return 0; + } + }; + + /** Default character set name. */ + protected static final String DEFAULT_CHARSET_NAME = "UTF-8"; + + /** Default character set. */ + protected static final Charset DEFAULT_CHARSET = Charset.forName(DEFAULT_CHARSET_NAME); + + protected final ResourceBinder binder; + + protected final GroovyScriptInstantiator instantiator; + + protected final GroovyClassLoaderProvider classLoaderProvider; + + protected final Map resources = Collections.synchronizedMap(new HashMap()); + + public GroovyJaxrsPublisher(ResourceBinder binder, GroovyScriptInstantiator instantiator, + GroovyClassLoaderProvider classLoaderProvider) + { + this.binder = binder; + this.instantiator = instantiator; + this.classLoaderProvider = classLoaderProvider; + } + + /** + * Create GroovyJaxrsPublisher which is able publish per-request and + * singleton resources. Any required dependencies for per-request resource + * injected by {@link PerRequestObjectFactory}, instance of singleton + * resources will be created by {@link GroovyScriptInstantiator}. + * + * @param binder resource binder + * @param instantiator instantiate java object from given groovy source + */ + public GroovyJaxrsPublisher(ResourceBinder binder, GroovyScriptInstantiator instantiator) + { + this(binder, instantiator, new GroovyClassLoaderProvider()); + } + + /** + * @return get underling groovy class loader + */ + @Deprecated + public GroovyClassLoader getGroovyClassLoader() + { + return classLoaderProvider.getGroovyClassLoader(); + } + + /** + * Set groovy class loader. + * + * @param gcl groovy class loader + * @throws NullPointerException if gcl == null + */ + @Deprecated + public void setGroovyClassLoader(GroovyClassLoader gcl) + { + LOG.warn("Method setGroovyClassLoader is deprecated."); + } + + /** + * Get resource corresponded to specified id resourceId . + * + * @param resourceId resource id + * @return resource or null + */ + public ObjectFactory getResource(ResourceId resourceId) + { + String path = resources.get(resourceId); + if (path == null) + return null; + + UriPattern pattern = new UriPattern(path); + List> rootResources = binder.getResources(); + synchronized (rootResources) + { + for (ObjectFactory res : rootResources) + { + if (res.getObjectModel().getUriPattern().equals(pattern)) + return res; + } + } + // If resource not exists any more but still in mapping. + resources.remove(resourceId); + return null; + } + + /** + * Check is groovy resource with specified id is published or not + * + * @param resourceId id of resource to be checked + * @return true if resource is published and false + * otherwise + */ + public boolean isPublished(ResourceId resourceId) + { + return null != getResource(resourceId); + } + + /** + * Parse given stream and publish result as per-request RESTful service. + * + * @param in stream which contains groovy source code of RESTful service + * @param resourceId id to be assigned to resource + * @param properties optional resource properties. This parameter may be + * null + * @throws NullPointerException if resourceId == null + * @throws ResourcePublicationException see + * {@link ResourceBinder#addResource(Class, MultivaluedMap)} + * @throws CompilationFailedException if compilation fails from source errors + */ + public void publishPerRequest(InputStream in, ResourceId resourceId, MultivaluedMap properties) + { + publishPerRequest(in, resourceId, properties, null, null); + } + + /** + * Parse given stream and publish result as per-request RESTful service. + * + * @param in stream which contains Groovy source code of RESTful service + * @param resourceId id to be assigned to resource + * @param properties optional resource properties. This parameter may be + * null + * @param src additional path to Groovy sources + * @param files Groovy source files to be added in build path directly + * @throws NullPointerException if resourceId == null + * @throws ResourcePublicationException see + * {@link ResourceBinder#addResource(Class, MultivaluedMap)} + * @throws CompilationFailedException if compilation fails from source errors + */ + public void publishPerRequest(final InputStream in, final ResourceId resourceId, + final MultivaluedMap properties, final SourceFolder[] src, final SourceFile[] files) + { + Class rc; + try + { + ExtendedGroovyClassLoader cl = + (src == null) ? classLoaderProvider.getGroovyClassLoader() : classLoaderProvider + .getGroovyClassLoader(src); + rc = cl.parseClass(in, resourceId.getId(), files); + } + catch (MalformedURLException e) + { + throw new IllegalArgumentException(e.getMessage(), e); + } + + binder.addResource(rc, properties); + resources.put(resourceId, rc.getAnnotation(Path.class).value()); + } + + /** + * Parse given source and publish result as per-request RESTful + * service. + * + * @param source groovy source code of RESTful service + * @param resourceId id to be assigned to resource + * @param properties optional resource properties. This parameter may be + * null + * @throws NullPointerException if resourceId == null + * @throws ResourcePublicationException see + * {@link ResourceBinder#addResource(Class, MultivaluedMap)} + * @throws CompilationFailedException if compilation fails from source errors + */ + public final void publishPerRequest(String source, ResourceId resourceId, MultivaluedMap properties) + { + publishPerRequest(source, DEFAULT_CHARSET, resourceId, properties, null, null); + } + + /** + * Parse given source and publish result as per-request RESTful + * service. + * + * @param source groovy source code of RESTful service + * @param resourceId id to be assigned to resource + * @param properties optional resource properties. This parameter may be + * null + * @param src additional path to Groovy sources + * @param files Groovy source files to be added in build path directly + * @throws NullPointerException if resourceId == null + * @throws ResourcePublicationException see + * {@link ResourceBinder#addResource(Class, MultivaluedMap)} + * @throws CompilationFailedException if compilation fails from source errors + */ + public final void publishPerRequest(String source, ResourceId resourceId, MultivaluedMap properties, + SourceFolder[] src, SourceFile[] files) + { + publishPerRequest(source, DEFAULT_CHARSET, resourceId, properties, src, files); + } + + /** + * Parse given source and publish result as per-request RESTful + * service. + * + * @param source groovy source code of RESTful service + * @param charset source string charset. May be null than + * default charset will be in use + * @param resourceId id to be assigned to resource + * @param properties optional resource properties. This parameter may be + * null. + * @throws UnsupportedCharsetException if charset is unsupported + * @throws NullPointerException if resourceId == null + * @throws ResourcePublicationException see + * {@link ResourceBinder#addResource(Class, MultivaluedMap)} + * @throws CompilationFailedException if compilation fails from source errors + */ + public final void publishPerRequest(String source, String charset, ResourceId resourceId, + MultivaluedMap properties) + { + publishPerRequest(source, charset == null ? DEFAULT_CHARSET : Charset.forName(charset), resourceId, properties, + null, null); + } + + /** + * Parse given source and publish result as per-request RESTful + * service. + * + * @param source groovy source code of RESTful service + * @param charset source string charset. May be null than + * default charset will be in use + * @param resourceId id to be assigned to resource + * @param properties optional resource properties. This parameter may be + * null. + * @param src additional path to Groovy sources + * @param files Groovy source files to be added in build path directly + * @throws UnsupportedCharsetException if charset is unsupported + * @throws NullPointerException if resourceId == null + * @throws ResourcePublicationException see + * {@link ResourceBinder#addResource(Class, MultivaluedMap)} + * @throws CompilationFailedException if compilation fails from source errors + */ + public final void publishPerRequest(String source, String charset, ResourceId resourceId, + MultivaluedMap properties, SourceFolder[] src, SourceFile[] files) + { + publishPerRequest(source, charset == null ? DEFAULT_CHARSET : Charset.forName(charset), resourceId, properties, + src, files); + } + + /** + * Parse given stream and publish result as singleton RESTful service. + * + * @param in stream which contains groovy source code of RESTful service + * @param resourceId id to be assigned to resource + * @param properties optional resource properties. This parameter may be + * null + * @throws NullPointerException if resourceId == null + * @throws ResourcePublicationException see + * {@link ResourceBinder#addResource(Object, MultivaluedMap)} + * @throws CompilationFailedException if compilation fails from source errors + */ + public void publishSingleton(InputStream in, ResourceId resourceId, MultivaluedMap properties) + { + publishSingleton(in, resourceId, properties, null, null); + } + + /** + * Parse given stream and publish result as singleton RESTful service. + * + * @param in stream which contains groovy source code of RESTful service + * @param resourceId id to be assigned to resource + * @param properties optional resource properties. This parameter may be + * null + * @param src additional path to Groovy sources + * @param files Groovy source files to be added in build path directly + * @throws NullPointerException if resourceId == null + * @throws ResourcePublicationException see + * {@link ResourceBinder#addResource(Object, MultivaluedMap)} + * @throws CompilationFailedException if compilation fails from source errors + */ + public void publishSingleton(final InputStream in, final ResourceId resourceId, + MultivaluedMap properties, final SourceFolder[] src, final SourceFile[] files) + { + Object resource; + try + { + ExtendedGroovyClassLoader cl = + (src == null) ? classLoaderProvider.getGroovyClassLoader() : classLoaderProvider.getGroovyClassLoader(src); + @SuppressWarnings("rawtypes") + Class clazz = cl.parseClass(in, resourceId.getId(), files); + resource = createInstance(clazz); + } + catch (IllegalArgumentException e) + { + throw new ResourcePublicationException(e.getMessage()); + } + catch (InstantiationException e) + { + throw new ResourcePublicationException(e.getMessage()); + } + catch (IllegalAccessException e) + { + throw new ResourcePublicationException(e.getMessage()); + } + catch (InvocationTargetException e) + { + throw new ResourcePublicationException(e.getMessage()); + } + catch (MalformedURLException e) + { + throw new IllegalArgumentException(e.getMessage(), e); + } + binder.addResource(resource, properties); + resources.put(resourceId, resource.getClass().getAnnotation(Path.class).value()); + } + + /** + * Parse given source and publish result as singleton RESTful + * service. + * + * @param source groovy source code of RESTful service + * @param resourceId name of resource + * @param properties optional resource properties. This parameter may be + * null. + * @throws NullPointerException if resourceId == null + * @throws ResourcePublicationException see + * {@link ResourceBinder#addResource(Object, MultivaluedMap)} + * @throws CompilationFailedException if compilation fails from source errors + */ + public final void publishSingleton(String source, ResourceId resourceId, MultivaluedMap properties) + { + publishSingleton(source, DEFAULT_CHARSET, resourceId, properties, null, null); + } + + /** + * Parse given source and publish result as singleton RESTful + * service. + * + * @param source groovy source code of RESTful service + * @param resourceId name of resource + * @param properties optional resource properties. This parameter may be + * null. + * @param src additional path to Groovy sources + * @param files Groovy source files to be added in build path directly + * @throws NullPointerException if resourceId == null + * @throws ResourcePublicationException see + * {@link ResourceBinder#addResource(Object, MultivaluedMap)} + * @throws CompilationFailedException if compilation fails from source errors + */ + public final void publishSingleton(String source, ResourceId resourceId, MultivaluedMap properties, + SourceFolder[] src, SourceFile[] files) + { + publishSingleton(source, DEFAULT_CHARSET, resourceId, properties, src, files); + } + + /** + * Parse given source and publish result as singleton RESTful + * service. + * + * @param source groovy source code of RESTful service + * @param charset source string charset. May be null than + * default charset will be in use + * @param resourceId name of resource + * @param properties optional resource properties. This parameter may be + * null. + * @throws UnsupportedCharsetException if charset is unsupported + * @throws NullPointerException if resourceId == null + * @throws ResourcePublicationException see + * {@link ResourceBinder#addResource(Object, MultivaluedMap)} + * @throws CompilationFailedException if compilation fails from source errors + */ + public final void publishSingleton(String source, String charset, ResourceId resourceId, + MultivaluedMap properties) + { + publishSingleton(source, charset == null ? DEFAULT_CHARSET : Charset.forName(charset), resourceId, properties, + null, null); + } + + /** + * Parse given source and publish result as singleton RESTful + * service. + * + * @param source groovy source code of RESTful service + * @param charset source string charset. May be null than + * default charset will be in use + * @param resourceId name of resource + * @param properties optional resource properties. This parameter may be + * null. + * @param src additional path to Groovy sources + * @param files Groovy source files to be added in build path directly + * @throws UnsupportedCharsetException if charset is unsupported + * @throws NullPointerException if resourceId == null + * @throws ResourcePublicationException see + * {@link ResourceBinder#addResource(Object, MultivaluedMap)} + * @throws CompilationFailedException if compilation fails from source errors + */ + public final void publishSingleton(String source, String charset, ResourceId resourceId, + MultivaluedMap properties, SourceFolder[] src, SourceFile[] files) + { + publishSingleton(source, charset == null ? DEFAULT_CHARSET : Charset.forName(charset), resourceId, properties, + src, files); + } + + /** + * Unpublish resource with specified id. + * + * @param resourceId id of resource to be unpublished + * @return true if resource was published and false + * otherwise, e.g. because there is not resource corresponded to + * supplied resourceId + */ + public ObjectFactory unpublishResource(ResourceId resourceId) + { + String path = resources.get(resourceId); + if (path == null) + return null; + ObjectFactory resource = binder.removeResource(path); + if (resource != null) + resources.remove(resourceId); + return resource; + } + + /** + * Validate does stream contain Groovy source code which is conforms with + * requirement to JAX-RS resource. + * + * @param in Groovy source stream + * @param name script name. This name will be used by GroovyClassLoader to + * identify script, e.g. specified name will be used in error + * message in compilation of Groovy fails. If this parameter is + * null then GroovyClassLoader will use automatically + * generated name + * @param src additional path to Groovy sources + * @param files Groovy source files to be added in build path directly + * @throws MalformedScriptException if source has errors or there is no + * required JAX-RS annotation + */ + public void validateResource(final InputStream in, final String name, final SourceFolder[] src, + final SourceFile[] files) throws MalformedScriptException + { + try + { + ExtendedGroovyClassLoader cl = + (src == null) ? classLoaderProvider.getGroovyClassLoader() : classLoaderProvider + .getGroovyClassLoader(src); + cl.parseClass(in, (name != null && name.length() > 0) ? name : cl.generateScriptName(), files); + } + catch (MalformedURLException e) + { + // MalformedURLException + throw new IllegalArgumentException(e.getMessage(), e); + } + catch (CompilationFailedException e) + { + throw new MalformedScriptException(e.getMessage()); + } + /// XXX : Temporary disable resource class validation. Just try to compile + // class and assume resource class is OK if compilation is successful. + /*try + { + new AbstractResourceDescriptorImpl(rc).accept(ResourceDescriptorValidator.getInstance()); + } + catch (RuntimeException e) + { + throw new MalformedScriptException(e.getMessage()); + }*/ + } + + /** + * Validate does stream contain Groovy source code which is conforms with + * requirement to JAX-RS resource. + * + * @param in Groovy source stream + * @param name script name. This name will be used by GroovyClassLoader to + * identify script, e.g. specified name will be used in error + * message in compilation of Groovy fails. If this parameter is + * null then GroovyClassLoader will use automatically + * generated name + * @throws MalformedScriptException if source has errors or there is no + * required JAX-RS annotation + */ + public void validateResource(InputStream in, String name) throws MalformedScriptException + { + validateResource(in, name, null, null); + } + + /** + * Validate does source contain Groovy source code which is + * conforms with requirement to JAX-RS resource. + * + * @param source Groovy source code as String + * @param charset source string charset. May be null than + * default charset will be in use + * @param name script name. This name will be used by GroovyClassLoader to + * identify script, e.g. specified name will be used in error + * message in compilation of Groovy fails. If this parameter is + * null then GroovyClassLoader will use automatically + * generated name + * @param src additional path to Groovy sources + * @param files Groovy source files to be added in build path directly + * @throws MalformedScriptException if source has errors or there is no + * required JAX-RS annotation + */ + public final void validateResource(String source, String charset, String name, SourceFolder[] src, SourceFile[] files) + throws MalformedScriptException + { + validateResource(source, charset == null ? DEFAULT_CHARSET : Charset.forName(charset), name, src, files); + } + + /** + * Validate does source contain Groovy source code which is + * conforms with requirement to JAX-RS resource. + * + * @param source Groovy source code as String + * @param name script name. This name will be used by GroovyClassLoader to + * identify script, e.g. specified name will be used in error + * message in compilation of Groovy fails. If this parameter is + * null then GroovyClassLoader will use automatically + * generated name + * @param src additional path to Groovy sources + * @param files Groovy source files to be added in build path directly + * @throws MalformedScriptException if source has errors or there is no + * required JAX-RS annotation + */ + public final void validateResource(String source, String name, SourceFolder[] src, SourceFile[] files) + throws MalformedScriptException + { + validateResource(source, DEFAULT_CHARSET, name, src, files); + } + + /** + * Validate does source contain Groovy source code which is + * conforms with requirement to JAX-RS resource. + * + * @param source Groovy source code as String + * @param name script name. This name will be used by GroovyClassLoader to + * identify script, e.g. specified name will be used in error + * message in compilation of Groovy fails. If this parameter is + * null then GroovyClassLoader will use automatically + * generated name + * @throws MalformedScriptException if source has errors or there is no + * required JAX-RS annotation + */ + public final void validateResource(String source, String name) throws MalformedScriptException + { + validateResource(source, DEFAULT_CHARSET, name, null, null); + } + + @SuppressWarnings("rawtypes") + protected Object createInstance(Class clazz) throws IllegalArgumentException, InstantiationException, + IllegalAccessException, InvocationTargetException + { + ExoContainer container = ExoContainerContext.getCurrentContainer(); + Constructor[] constructors = clazz.getConstructors(); + //Sort constructors by number of parameters. With more parameters must be first. + Arrays.sort(constructors, constructorComparator); + l : for (Constructor c : constructors) + { + Class[] parameterTypes = c.getParameterTypes(); + if (parameterTypes.length == 0) + return c.newInstance(); + Object[] parameters = new Object[parameterTypes.length]; + for (int i = 0; i < parameterTypes.length; i++) + { + Object param = container.getComponentInstanceOfType(parameterTypes[i]); + if (param == null) + continue l; + parameters[i] = param; + } + return c.newInstance(parameters); + } + throw new ResourcePublicationException("Unbale create instance of class " + clazz.getName() + + ". Required constructor's dependencies can't be resolved. "); + } + + private void publishPerRequest(String source, Charset charset, ResourceId resourceId, + MultivaluedMap properties, SourceFolder[] src, SourceFile[] files) + { + byte[] bytes = source.getBytes(charset); + publishPerRequest(new ByteArrayInputStream(bytes), resourceId, properties, src, files); + } + + private void publishSingleton(String source, Charset charset, ResourceId resourceId, + MultivaluedMap properties, SourceFolder[] src, SourceFile[] files) + { + byte[] bytes = source.getBytes(charset); + publishSingleton(new ByteArrayInputStream(bytes), resourceId, properties, src, files); + } + + private void validateResource(String source, Charset charset, String name, SourceFolder[] src, SourceFile[] files) + throws MalformedScriptException + { + byte[] bytes = source.getBytes(charset); + validateResource(new ByteArrayInputStream(bytes), name, src, files); + } + + /** + * Create {@link GroovyCodeSource} from given location (URL). + * + * @param url groovy source url + * @exception java.io.IOException + * @return GroovyCodeSource + */ + protected GroovyCodeSource createCodeSource(final URL url) throws IOException + { + GroovyCodeSource gcs = new GroovyCodeSource(url); + gcs.setCachable(false); + return gcs; + } +} diff --git a/exo.jcr.component.ext/src/main/java/org/exoplatform/services/rest/ext/groovy/MalformedScriptException.java b/exo.jcr.component.ext/src/main/java/org/exoplatform/services/rest/ext/groovy/MalformedScriptException.java new file mode 100644 index 0000000000..82e0e56e86 --- /dev/null +++ b/exo.jcr.component.ext/src/main/java/org/exoplatform/services/rest/ext/groovy/MalformedScriptException.java @@ -0,0 +1,38 @@ +/* + * This file is part of the Meeds project (https://meeds.io/). + * Copyright (C) 2020 Meeds Association + * contact@meeds.io + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser 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 + * Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.exoplatform.services.rest.ext.groovy; + +/** + * Thrown if Groovy script is not comply with requirement to JAX-RS resources. + * + * @author Andrey Parfonov + * @version $Id$ + */ +@SuppressWarnings("serial") +public class MalformedScriptException extends Exception { + /** + * @param message detail message about wrong with Groovy script. + */ + public MalformedScriptException(String message) { + super(message); + } + + public MalformedScriptException(String message, Throwable throwable) { + super(message, throwable); + } + +} diff --git a/exo.jcr.component.ext/src/main/java/org/exoplatform/services/rest/ext/groovy/ResourceId.java b/exo.jcr.component.ext/src/main/java/org/exoplatform/services/rest/ext/groovy/ResourceId.java new file mode 100644 index 0000000000..1ac0d641c0 --- /dev/null +++ b/exo.jcr.component.ext/src/main/java/org/exoplatform/services/rest/ext/groovy/ResourceId.java @@ -0,0 +1,34 @@ +/* + * This file is part of the Meeds project (https://meeds.io/). + * Copyright (C) 2020 Meeds Association + * contact@meeds.io + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser 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 + * Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package org.exoplatform.services.rest.ext.groovy; + +/** + * @author Andrey Parfonov + * @version $Id$ + */ +public interface ResourceId +{ + + /** + * Gets the id of resource as string + * + * @return the resource id + */ + String getId(); + +} diff --git a/exo.jcr.component.ext/src/main/java/org/exoplatform/services/rest/ext/groovy/SourceFile.java b/exo.jcr.component.ext/src/main/java/org/exoplatform/services/rest/ext/groovy/SourceFile.java new file mode 100644 index 0000000000..7fe36d536b --- /dev/null +++ b/exo.jcr.component.ext/src/main/java/org/exoplatform/services/rest/ext/groovy/SourceFile.java @@ -0,0 +1,33 @@ +/* + * This file is part of the Meeds project (https://meeds.io/). + * Copyright (C) 2020 Meeds Association + * contact@meeds.io + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser 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 + * Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.exoplatform.services.rest.ext.groovy; + +import java.net.URL; + +/** + * Describe location of Groovy source file. + * + * @author Andrey Parfonov + * @version $Id$ + */ +public class SourceFile extends ClassPathEntry +{ + public SourceFile(URL path) + { + super(path); + } +} diff --git a/exo.jcr.component.ext/src/main/java/org/exoplatform/services/rest/ext/groovy/SourceFolder.java b/exo.jcr.component.ext/src/main/java/org/exoplatform/services/rest/ext/groovy/SourceFolder.java new file mode 100644 index 0000000000..01d3ad02c4 --- /dev/null +++ b/exo.jcr.component.ext/src/main/java/org/exoplatform/services/rest/ext/groovy/SourceFolder.java @@ -0,0 +1,33 @@ +/* + * This file is part of the Meeds project (https://meeds.io/). + * Copyright (C) 2020 Meeds Association + * contact@meeds.io + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser 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 + * Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.exoplatform.services.rest.ext.groovy; + +import java.net.URL; + +/** + * Folder with groovy sources. + * + * @author Andrey Parfonov + * @version $Id$ + */ +public class SourceFolder extends ClassPathEntry +{ + public SourceFolder(URL path) + { + super(path); + } +} diff --git a/exo.jcr.component.ext/src/main/java/org/exoplatform/services/script/groovy/GroovyScriptInstantiator.java b/exo.jcr.component.ext/src/main/java/org/exoplatform/services/script/groovy/GroovyScriptInstantiator.java new file mode 100644 index 0000000000..c4d458279a --- /dev/null +++ b/exo.jcr.component.ext/src/main/java/org/exoplatform/services/script/groovy/GroovyScriptInstantiator.java @@ -0,0 +1,302 @@ +/* + * Copyright (C) 2009 eXo Platform SAS. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.exoplatform.services.script.groovy; + +import groovy.lang.GroovyClassLoader; +import groovy.lang.GroovyCodeSource; + +import org.exoplatform.commons.utils.IOUtil; +import org.exoplatform.container.ExoContainer; +import org.exoplatform.container.ExoContainerContext; +import org.exoplatform.container.component.ComponentPlugin; +import org.exoplatform.container.spi.DefinitionByType; +import org.exoplatform.services.log.ExoLogger; +import org.exoplatform.services.log.Log; +import org.exoplatform.services.script.groovy.jarjar.JarJarClassLoader; + +import java.io.BufferedInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Constructor; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author Andrey Parfonov + * @version $Id: $ + */ +@DefinitionByType +public class GroovyScriptInstantiator +{ + + /** Our logger. */ + private static final Log LOG = ExoLogger.getLogger(GroovyScriptInstantiator.class); + + /** + * eXo Container. + */ + private ExoContainer container; + + /** The global mapping. */ + private Map mapping; + + /** + * @param containerContext container context + */ + public GroovyScriptInstantiator(ExoContainerContext containerContext) + { + this.container = containerContext.getContainer(); + this.mapping = Collections.synchronizedMap(new HashMap()); + } + + /** + * Load script from given address. + * + * @param spec the resource's address. + * @return the object created from groovy script. + * @throws MalformedURLException if parameter url have wrong + * format. + * @throws IOException if can't load script from given url. + * @see GroovyScriptInstantiator#instantiateScript(URL) + * @see GroovyScriptInstantiator#instantiateScript(InputStream) + */ + public Object instantiateScript(String spec) throws MalformedURLException, IOException + { + return instantiateScript(new URL(spec)); + } + + /** + * Load script from given address. + * + * @param url the resource's address. + * @return the object created from groovy script. + * @throws IOException if can't load script from given url. + * @see GroovyScriptInstantiator#instantiateScript(InputStream) + */ + public Object instantiateScript(URL url) throws IOException + { + String name = url.toString(); + return instantiateScript(new BufferedInputStream(url.openStream()), name); + } + + /** + * Parse given stream, the stream must represents groovy script. + * + * @param stream the stream represented groovy script. + * @return the object created from groovy script. + * @throws IOException if stream can't be parsed or object can't be created + * cause to illegal content of stream + */ + public Object instantiateScript(InputStream stream) throws IOException + { + return instantiateScript(stream, null); + } + + /** + * Parse given stream, the stream must represents groovy script. + * + * @param stream the stream represented groovy script. + * @param name script name is null or empty string that groovy completer will + * use default name + * @return the object created from groovy script. + * @throws IOException if stream can't be parsed or object can't be created + * cause to illegal content of stream + */ + public Object instantiateScript(InputStream stream, String name) throws IOException + { + GroovyClassLoader loader; + if (mapping.size() > 0) + { + JarJarClassLoader jarjarLoader = new JarJarClassLoader(); + + jarjarLoader.addMapping(mapping); + loader = jarjarLoader; + } + else + { + loader = new GroovyClassLoader(); + } + return instantiateScript(stream, name, loader); + } + + /** + * Parse given stream, the stream must represents groovy script and use given + * class-loader. If loader == null then + * {@link groovy.lang.GroovyClassLoader} will be is use. + * + * @param stream the stream represented groovy script. + * @param name script name is null or empty string that groovy completer will + * use default name + * @param loader GroovyClassLoader or null + * @return the object created from groovy script. + * @throws IOException if stream can't be parsed or object can't be created + * cause to illegal content of stream + */ + public Object instantiateScript(final InputStream stream, final String name, GroovyClassLoader loader) + throws IOException + { + if (loader == null) + { + loader = new GroovyClassLoader(); + } + Class clazz = null; + final GroovyClassLoader fLoader = loader; + clazz = fLoader.parseClass(IOUtil.getStreamContentAsString(stream)); + + try + { + return createObject(clazz); + } + catch (Exception e) + { + throw new RuntimeException("Can't instantiate groovy script: " + e.getMessage(), e); + } + finally + { + if(stream != null) { + try { + stream.close(); + } catch (IOException e) { + // Stream already closed + } + } + } + } + + /** + * Instantiate script from give {@link GroovyCodeSource} and use given + * class-loader. If loader == null then + * {@link groovy.lang.GroovyClassLoader} will be is use. + * + * @param codeSource code source + * @param loader + * @return + */ + public Object instantiateScript(final GroovyCodeSource codeSource, GroovyClassLoader loader) + { + if (loader == null) + { + loader = new GroovyClassLoader(); + } + + final GroovyClassLoader fLoader = loader; + Class clazz = fLoader.parseClass(codeSource); + + try + { + return createObject(clazz); + } + catch (Exception e) + { + throw new RuntimeException("Can't instantiate groovy script: " + e.getMessage(), e); + } + } + + /** + * Created object from given class, if class has parameters in constructor, + * then this parameters will be searched in container. + * + * @param clazz java-groovy class + */ + private Object createObject(Class clazz) throws Exception + { + + Constructor[] constructors = clazz.getConstructors(); + + /* + * Sort constructors by number of parameters. With more parameters must be + * first. + */ + Arrays.sort(constructors, COMPARATOR); + + l : for (Constructor c : constructors) + { + Class[] parameterTypes = c.getParameterTypes(); + if (parameterTypes.length == 0) + { + return c.newInstance(); + } + + List parameters = new ArrayList(parameterTypes.length); + + for (Class parameterType : parameterTypes) + { + Object param = container.getComponentInstanceOfType(parameterType); + if (param == null) + { + continue l; + } + parameters.add(param); + } + + return c.newInstance(parameters.toArray(new Object[parameters.size()])); + } + return null; + + } + + private static final ConstructorsComparator COMPARATOR = new ConstructorsComparator(); + + /** + * Sorts array of constructors by number of parameters. + */ + private static class ConstructorsComparator implements Comparator> + { + + /** + * {@inheritDoc} + */ + public int compare(Constructor constructor1, Constructor constructor2) + { + int c1 = constructor1.getParameterTypes().length; + int c2 = constructor2.getParameterTypes().length; + if (c1 < c2) + { + return 1; + } + if (c1 > c2) + { + return -1; + } + return 0; + } + + } + + public void addPlugin(ComponentPlugin plugin) + { + if (plugin instanceof GroovyScriptJarJarPlugin) + { + GroovyScriptJarJarPlugin jarjarPlugin = (GroovyScriptJarJarPlugin)plugin; + if (LOG.isDebugEnabled()) + { + LOG.debug("Add mapping to groovy instantiator:" + jarjarPlugin.getMapping()); + } + mapping.putAll(jarjarPlugin.getMapping()); + } + } + +} diff --git a/exo.jcr.component.ext/src/main/java/org/exoplatform/services/script/groovy/GroovyScriptJarJarPlugin.java b/exo.jcr.component.ext/src/main/java/org/exoplatform/services/script/groovy/GroovyScriptJarJarPlugin.java new file mode 100644 index 0000000000..39d5e263c8 --- /dev/null +++ b/exo.jcr.component.ext/src/main/java/org/exoplatform/services/script/groovy/GroovyScriptJarJarPlugin.java @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2009 eXo Platform SAS. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.exoplatform.services.script.groovy; + +import org.exoplatform.container.component.BaseComponentPlugin; +import org.exoplatform.container.xml.InitParams; +import org.exoplatform.services.log.ExoLogger; +import org.exoplatform.services.log.Log; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +/** + * A plugin that retrieves a mapping from the init param named mapping. The param + * is a multivalued string, each string has the format {@literal left->right} where left and right + * are package full qualified names. + * + * @author Julien Viet + * @version $Revision$ + */ +public class GroovyScriptJarJarPlugin extends BaseComponentPlugin +{ + + /** The mapping state. */ + private final Map mapping = new HashMap(); + + /** Our logger. */ + private final static Log LOG = ExoLogger.getLogger("exo.core.component.script.groovy.GroovyScriptJarJarPlugin"); + + public GroovyScriptJarJarPlugin(InitParams params) + { + + List values = params.getValuesParam("mapping").getValues(); + + if (mapping == null) + { + LOG.warn("Was expecting a mapping init param"); + } + else + { + for (Iterator i = values.iterator(); i.hasNext();) + { + String rule = i.next(); + + String[] tmp = rule.split("\\-\\>"); + if (tmp.length == 2) + { + String left = tmp[0].trim(); + String right = tmp[1].trim(); + mapping.put(left, right); + LOG.debug("Added mapping rule " + left + " -> " + right); + } + else + { + LOG.warn("Malformed mapping rule:" + rule); + } + } + } + } + + public Map getMapping() + { + return mapping; + } +} diff --git a/exo.jcr.component.ext/src/main/java/org/exoplatform/services/script/groovy/GroovyScriptURLLoaderPlugin.java b/exo.jcr.component.ext/src/main/java/org/exoplatform/services/script/groovy/GroovyScriptURLLoaderPlugin.java new file mode 100644 index 0000000000..735a50a731 --- /dev/null +++ b/exo.jcr.component.ext/src/main/java/org/exoplatform/services/script/groovy/GroovyScriptURLLoaderPlugin.java @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2009 eXo Platform SAS. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.exoplatform.services.script.groovy; + +import org.exoplatform.container.component.BaseComponentPlugin; +import org.exoplatform.container.xml.InitParams; +import org.exoplatform.container.xml.ObjectParameter; + +import java.util.ArrayList; +import java.util.List; + +/** + * Should be used by third part service for loading script at start. + * + * @author Andrey Parfonov + * @version $Id: $ + */ +public class GroovyScriptURLLoaderPlugin extends BaseComponentPlugin +{ + + private List urls; + + public GroovyScriptURLLoaderPlugin(InitParams params) + { + if (params != null) + { + ObjectParameter param = params.getObjectParam("scripts"); + if (param != null) + urls = ((GroovyScriptURLs)param.getObject()).getUrls(); + } + } + + /** + * @return list of URL from configuration. + */ + public List getUrls() + { + return urls; + } + + /** + * Should be used in configuration as object parameter. + */ + public static class GroovyScriptURLs + { + + private List urls = new ArrayList(); + + public List getUrls() + { + return urls; + } + + public void setUrls(List urls) + { + this.urls = urls; + } + } + +} diff --git a/exo.jcr.component.ext/src/main/java/org/exoplatform/services/script/groovy/jarjar/JarJarClassLoader.java b/exo.jcr.component.ext/src/main/java/org/exoplatform/services/script/groovy/jarjar/JarJarClassLoader.java new file mode 100644 index 0000000000..404d66dce8 --- /dev/null +++ b/exo.jcr.component.ext/src/main/java/org/exoplatform/services/script/groovy/jarjar/JarJarClassLoader.java @@ -0,0 +1,145 @@ +/* + * Copyright (C) 2009 eXo Platform SAS. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.exoplatform.services.script.groovy.jarjar; + +import groovy.lang.GroovyClassLoader; + +import org.codehaus.groovy.ast.ClassNode; +import org.codehaus.groovy.ast.ImportNode; +import org.codehaus.groovy.ast.ModuleNode; +import org.codehaus.groovy.classgen.GeneratorContext; +import org.codehaus.groovy.control.CompilationFailedException; +import org.codehaus.groovy.control.CompilationUnit; +import org.codehaus.groovy.control.CompilerConfiguration; +import org.codehaus.groovy.control.Phases; +import org.codehaus.groovy.control.SourceUnit; + +import java.security.CodeSource; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +/** + * A groovy class loader that performs jar jar operations. + * + * @author Julien Viet + * @version $Revision$ + */ +public class JarJarClassLoader extends GroovyClassLoader +{ + + private Package root = new Package(); + + public JarJarClassLoader() + { + } + + public JarJarClassLoader(ClassLoader classLoader) + { + super(classLoader); + } + + public JarJarClassLoader(GroovyClassLoader groovyClassLoader) + { + super(groovyClassLoader); + } + + public JarJarClassLoader(ClassLoader classLoader, CompilerConfiguration compilerConfiguration, boolean b) + { + super(classLoader, compilerConfiguration, b); + } + + public JarJarClassLoader(ClassLoader classLoader, CompilerConfiguration compilerConfiguration) + { + super(classLoader, compilerConfiguration); + } + + public void addMapping(List source, List destination) + { + root.add(source, destination); + } + + public void addMapping(Map mapping) + { + for (Map.Entry entry : mapping.entrySet()) + { + addMapping(entry.getKey(), entry.getValue()); + } + } + + public void addMapping(String source, String destination) + { + List sourcePackage = Arrays.asList(source.split("\\.")); + List destinationPackage = Arrays.asList(destination.split("\\.")); + root.add(sourcePackage, destinationPackage); + } + + @Override + protected CompilationUnit createCompilationUnit(final CompilerConfiguration compilerConfiguration, + final CodeSource codeSource) + { + // + final CompilationUnit unit = JarJarClassLoader.super.createCompilationUnit(compilerConfiguration, codeSource); + + // + unit.addPhaseOperation(new CompilationUnit.PrimaryClassNodeOperation() + { + @Override + public void call(SourceUnit sourceUnit, GeneratorContext generatorContext, ClassNode classNode) + throws CompilationFailedException + { + + // + ModuleNode module = classNode.getModule(); + + // + for (Iterator i = module.getImports().iterator(); i.hasNext();) + { + ImportNode importNode = i.next(); + ClassNode cn = importNode.getType(); + String s = cn.getPackageName(); + List ss = root.map2(s); + if (ss != null) + { + StringBuilder sb = new StringBuilder(); + for (String n : ss) + { + sb.append(n).append('.'); + } + sb.append(cn.getNameWithoutPackage()); + String name = sb.toString(); + cn.setName(name); + } + } + + // + JarJarExpressionTransformer visitor = new JarJarExpressionTransformer(sourceUnit, root); + visitor.visitClass(classNode); + } + }, Phases.CONVERSION); + + return unit; + } + + static protected JarJarClassLoader createJarJarClassLoaderInPrivilegedMode(final ClassLoader classLoader) + { + return new JarJarClassLoader(classLoader); + } +} diff --git a/exo.jcr.component.ext/src/main/java/org/exoplatform/services/script/groovy/jarjar/JarJarExpressionTransformer.java b/exo.jcr.component.ext/src/main/java/org/exoplatform/services/script/groovy/jarjar/JarJarExpressionTransformer.java new file mode 100644 index 0000000000..126c5df09a --- /dev/null +++ b/exo.jcr.component.ext/src/main/java/org/exoplatform/services/script/groovy/jarjar/JarJarExpressionTransformer.java @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2009 eXo Platform SAS. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.exoplatform.services.script.groovy.jarjar; + +import org.codehaus.groovy.ast.ClassCodeExpressionTransformer; +import org.codehaus.groovy.ast.ClassHelper; +import org.codehaus.groovy.ast.ClassNode; +import org.codehaus.groovy.ast.expr.ConstantExpression; +import org.codehaus.groovy.ast.expr.Expression; +import org.codehaus.groovy.ast.expr.MethodCallExpression; +import org.codehaus.groovy.ast.expr.PropertyExpression; +import org.codehaus.groovy.ast.expr.VariableExpression; +import org.codehaus.groovy.control.SourceUnit; + +import java.util.List; + +/** + * @author Julien Viet + * @version $Revision$ + */ +class JarJarExpressionTransformer extends ClassCodeExpressionTransformer +{ + + /** . */ + private final SourceUnit source; + + /** . */ + private final Package root; + + JarJarExpressionTransformer(SourceUnit source, Package root) + { + this.source = source; + this.root = root; + } + + protected SourceUnit getSourceUnit() + { + return source; + } + + @Override + public Expression transform(Expression expression) + { + + // Handle method call expressions + if (expression instanceof MethodCallExpression) + { + MethodCallExpression mce = (MethodCallExpression)expression; + + // + if (mce.getObjectExpression() instanceof PropertyExpression) + { + PropertyExpression mce_pe = (PropertyExpression)mce.getObjectExpression(); + + // + Expression expr = bilto(mce_pe); + if (expr != null) + { + mce.setObjectExpression(expr); + } + } + } + return super.transform(expression); + } + + private Expression bilto(Expression exp) + { + + String s = exp.getText(); + + List ss = root.map2(exp); + + if (ss != null) + { + System.out.println(s + " -> " + ss); //NOSONAR + return createExpr(ss); + } + + return null; + } + + private static Expression createExpr(List packageName) + { + if (packageName.isEmpty()) + { + throw new IllegalStateException("Root does not have prefix"); + } + + // + if (packageName.size() == 1) + { + String name = packageName.get(0); + ClassNode objectCN = getClassNode(Object.class); + return new VariableExpression(name, objectCN); + } + else + { + Expression left = createExpr(packageName.subList(0, packageName.size() - 1)); + ConstantExpression right = new ConstantExpression(packageName.get(packageName.size() - 1)); + return new PropertyExpression(left, right); + } + } + + private static ClassNode getClassNode(Class clazz) + { + return ClassHelper.make(clazz); + } +} diff --git a/exo.jcr.component.ext/src/main/java/org/exoplatform/services/script/groovy/jarjar/Package.java b/exo.jcr.component.ext/src/main/java/org/exoplatform/services/script/groovy/jarjar/Package.java new file mode 100644 index 0000000000..da39d79414 --- /dev/null +++ b/exo.jcr.component.ext/src/main/java/org/exoplatform/services/script/groovy/jarjar/Package.java @@ -0,0 +1,240 @@ +/* + * Copyright (C) 2009 eXo Platform SAS. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.exoplatform.services.script.groovy.jarjar; + +import org.codehaus.groovy.ast.expr.ConstantExpression; +import org.codehaus.groovy.ast.expr.Expression; +import org.codehaus.groovy.ast.expr.PropertyExpression; +import org.codehaus.groovy.ast.expr.VariableExpression; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +/** + * Represents a package. + * + * @author Julien Viet + * @version $Revision$ + */ +class Package +{ + + /** . */ + private final Package parent; + + /** . */ + private final Map subMappers; + + /** . */ + private List target; + + public Package() + { + this.parent = null; + this.target = null; + this.subMappers = new HashMap(); + } + + private Package(Package parent) + { + this.parent = parent; + this.target = null; + this.subMappers = new HashMap(); + } + + public void add(List source, List target) + { + add(source.iterator(), target); + } + + public Package getSubPackage(String name) + { + return subMappers.get(name); + } + + private void add(Iterator source, List target) + { + if (source.hasNext()) + { + String name = source.next(); + Package sub = subMappers.get(name); + if (sub == null) + { + sub = new Package(this); + subMappers.put(name, sub); + } + sub.add(source, target); + } + else + { + if (this.target != null) + { + throw new IllegalStateException(); + } + this.target = Collections.unmodifiableList(target); + } + } + + public List getTarget() + { + return target; + } + + public String getName() + { + if (parent != null) + { + for (Map.Entry entry : parent.subMappers.entrySet()) + { + if (entry.getValue() == this) + { + return entry.getKey(); + } + } + } + return null; + } + + public Package map(Expression exp) + { + Package mapmap = null; + if (exp instanceof VariableExpression) + { + String name = ((VariableExpression)exp).getName(); + mapmap = getSubPackage(name); + } + else if (exp instanceof PropertyExpression) + { + PropertyExpression pe = (PropertyExpression)exp; + if (pe.getObjectExpression() instanceof VariableExpression) + { + mapmap = map(pe.getObjectExpression()); + } + else if (pe.getObjectExpression() instanceof PropertyExpression) + { + PropertyExpression pe_pe = (PropertyExpression)pe.getObjectExpression(); + mapmap = map(pe_pe); + } + else + { + // + } + if (mapmap != null) + { + ConstantExpression pe_ce = (ConstantExpression)pe.getProperty(); + if (pe_ce.getType().getName().equals("java.lang.String")) + { + Package sub_sub = mapmap.getSubPackage((String)pe_ce.getValue()); + if (sub_sub != null) + { + mapmap = sub_sub; + } + } + } + } + return mapmap; + } + + private static class BiltoVisitor extends PackageNameVisitor + { + + Package ref; + + List bilto = new LinkedList(); + + boolean repackaged = false; + + private BiltoVisitor(Package mapper) + { + this.ref = mapper; + } + + protected void accept(String name) + { + if (ref != null) + { + Package sub = ref.getSubPackage(name); + if (sub != null) + { + List target = sub.target; + if (target != null) + { + // Use the repackaging rule + bilto.clear(); + bilto.addAll(target); + repackaged = true; + } + else + { + // Add name + bilto.add(name); + } + ref = sub; + } + else + { + // Add name and set null as marker + bilto.add(name); + ref = null; + } + } + else + { + // Add name + bilto.add(name); + } + } + } + + public List map2(Expression expr) + { + BiltoVisitor visitor = new BiltoVisitor(this); + visitor.visit(expr); + return visitor.repackaged ? visitor.bilto : null; + } + + public List map2(String expr) + { + BiltoVisitor visitor = new BiltoVisitor(this); + visitor.visit(expr); + return visitor.repackaged ? visitor.bilto : null; + } + + @Override + public String toString() + { + StringBuilder sb = new StringBuilder(); + toString(sb); + return sb.toString(); + } + + private void toString(StringBuilder sb) + { + if (parent != null) + { + parent.toString(sb); + String name = getName(); + sb.append(".").append(name); + } + } +} diff --git a/exo.jcr.component.ext/src/main/java/org/exoplatform/services/script/groovy/jarjar/PackageNameVisitor.java b/exo.jcr.component.ext/src/main/java/org/exoplatform/services/script/groovy/jarjar/PackageNameVisitor.java new file mode 100644 index 0000000000..4806f99439 --- /dev/null +++ b/exo.jcr.component.ext/src/main/java/org/exoplatform/services/script/groovy/jarjar/PackageNameVisitor.java @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2009 eXo Platform SAS. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.exoplatform.services.script.groovy.jarjar; + +import org.codehaus.groovy.ast.expr.ConstantExpression; +import org.codehaus.groovy.ast.expr.Expression; +import org.codehaus.groovy.ast.expr.PropertyExpression; +import org.codehaus.groovy.ast.expr.VariableExpression; + +/** + * Implement visitor pattern for visiting a package name from left to right. + * + * @author Julien Viet + * @version $Revision$ + */ +abstract class PackageNameVisitor +{ + + /** + * Visit a name from its dotted string representation. + * + * @param packageName the package name + */ + public void visit(String packageName) + { + for (String name : packageName.split("\\.")) + { + accept(name); + } + } + + /** + * Visit a name from its groovy expression AST representation. + * + *

+ * The AST structure we are recognizing in that method is: + *

    + *
  • Expression -> VariableExpression
  • + *
  • Expression -> PropertyExpression[ObjectExpression,ConstantExpression] + *
+ *

+ * + *

A VariableExpression is considered as a terminal that is the top left term. Its name + * value is obtained by calling the getName() method.

+ * + *

A PropertyExpression is composed of an ObjectExpression and a Property. The ObjectExpression is evaluated + * recursively as an Expression. The Property must be a ConstantExpression and the name value is obtained + * by calling the getValue() method.

+ * + * @param expr the expression AST + */ + public void visit(Expression expr) + { + if (expr instanceof VariableExpression) + { + String name = ((VariableExpression)expr).getName(); + accept(name); + } + else if (expr instanceof PropertyExpression) + { + PropertyExpression pe = (PropertyExpression)expr; + visit(pe.getObjectExpression()); + ConstantExpression pe_ce = (ConstantExpression)pe.getProperty(); + accept((String)pe_ce.getValue()); + } + else + { + throw new UnsupportedOperationException("Do not support expression of type" + expr + " with text " + + expr.getText()); + } + } + + /** + * Implement this method to receive a name callback. + * + * @param name the name + */ + protected abstract void accept(String name); + +} diff --git a/exo.jcr.component.ext/src/test/java/a/ClassLitteral.java b/exo.jcr.component.ext/src/test/java/a/ClassLitteral.java new file mode 100644 index 0000000000..560cbc9c67 --- /dev/null +++ b/exo.jcr.component.ext/src/test/java/a/ClassLitteral.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2009 eXo Platform SAS. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package a; + +/** + * @author Julien Viet + * @version $Revision$ + */ +public class ClassLitteral +{ + + public static String getValue() + { + return "a"; + } +} diff --git a/exo.jcr.component.ext/src/test/java/a/ImportedClass.java b/exo.jcr.component.ext/src/test/java/a/ImportedClass.java new file mode 100644 index 0000000000..de5b8ed1a9 --- /dev/null +++ b/exo.jcr.component.ext/src/test/java/a/ImportedClass.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2009 eXo Platform SAS. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package a; + +/** + * @author Julien Viet + * @version $Revision$ + */ +public class ImportedClass +{ + + public String getValue() + { + return "a"; + } +} diff --git a/exo.jcr.component.ext/src/test/java/b/ClassLitteral.java b/exo.jcr.component.ext/src/test/java/b/ClassLitteral.java new file mode 100644 index 0000000000..7681806805 --- /dev/null +++ b/exo.jcr.component.ext/src/test/java/b/ClassLitteral.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2009 eXo Platform SAS. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package b; + +/** + * @author Julien Viet + * @version $Revision$ + */ +public class ClassLitteral +{ + + public static String getValue() + { + return "b"; + } +} \ No newline at end of file diff --git a/exo.jcr.component.ext/src/test/java/b/ImportedClass.java b/exo.jcr.component.ext/src/test/java/b/ImportedClass.java new file mode 100644 index 0000000000..4db7ef43f6 --- /dev/null +++ b/exo.jcr.component.ext/src/test/java/b/ImportedClass.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2009 eXo Platform SAS. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package b; + +/** + * @author Julien Viet + * @version $Revision$ + */ +public class ImportedClass +{ + + public String getValue() + { + return "b"; + } +} \ No newline at end of file diff --git a/exo.jcr.component.ext/src/test/java/org/exoplatform/services/rest/ext/BaseTest.java b/exo.jcr.component.ext/src/test/java/org/exoplatform/services/rest/ext/BaseTest.java new file mode 100644 index 0000000000..389cd1f7a7 --- /dev/null +++ b/exo.jcr.component.ext/src/test/java/org/exoplatform/services/rest/ext/BaseTest.java @@ -0,0 +1,67 @@ +/* + * This file is part of the Meeds project (https://meeds.io/). + * Copyright (C) 2020 Meeds Association + * contact@meeds.io + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser 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 + * Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package org.exoplatform.services.rest.ext; + +import junit.framework.TestCase; + +import org.exoplatform.container.StandaloneContainer; +import org.exoplatform.services.rest.ext.groovy.GroovyJaxrsPublisher; +import org.exoplatform.services.rest.impl.ApplicationContextImpl; +import org.exoplatform.services.rest.impl.ProviderBinder; +import org.exoplatform.services.rest.impl.RequestHandlerImpl; +import org.exoplatform.services.rest.impl.ResourceBinder; +import org.exoplatform.services.rest.tools.ResourceLauncher; + +/** + * @author Andrey Parfonov + * @version $Id$ + */ +public abstract class BaseTest extends TestCase +{ + protected StandaloneContainer container; + + protected ProviderBinder providers; + + protected ResourceBinder binder; + + protected RequestHandlerImpl requestHandler; + + protected GroovyJaxrsPublisher groovyPublisher; + + protected ResourceLauncher launcher; + + public void setUp() throws Exception + { + StandaloneContainer.setConfigurationPath("src/test/resources/conf/standalone/test-configuration.xml"); + container = StandaloneContainer.getInstance(); + binder = (ResourceBinder)container.getComponentInstanceOfType(ResourceBinder.class); + requestHandler = (RequestHandlerImpl)container.getComponentInstanceOfType(RequestHandlerImpl.class); + // reset providers to be sure it is clean + ProviderBinder.setInstance(new ProviderBinder()); + providers = ProviderBinder.getInstance(); + ApplicationContextImpl.setCurrent(new ApplicationContextImpl(null, null, providers)); + binder.clear(); + groovyPublisher = (GroovyJaxrsPublisher)container.getComponentInstanceOfType(GroovyJaxrsPublisher.class); + launcher = new ResourceLauncher(requestHandler); + } + + public void tearDown() throws Exception + { + } + +} \ No newline at end of file diff --git a/exo.jcr.component.ext/src/test/java/org/exoplatform/services/rest/ext/groovy/DefaultGroovyResourceLoaderTest.java b/exo.jcr.component.ext/src/test/java/org/exoplatform/services/rest/ext/groovy/DefaultGroovyResourceLoaderTest.java new file mode 100644 index 0000000000..40cc1d48e7 --- /dev/null +++ b/exo.jcr.component.ext/src/test/java/org/exoplatform/services/rest/ext/groovy/DefaultGroovyResourceLoaderTest.java @@ -0,0 +1,53 @@ +/* + * This file is part of the Meeds project (https://meeds.io/). + * Copyright (C) 2020 Meeds Association + * contact@meeds.io + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser 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 + * Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.exoplatform.services.rest.ext.groovy; + +import org.exoplatform.services.rest.ext.BaseTest; + +import java.io.File; +import java.net.URL; + +/** + * @author Nicolas Filotto + * @version $Id$ + * + */ +public class DefaultGroovyResourceLoaderTest extends BaseTest +{ + private DefaultGroovyResourceLoader groovyResourceLoader; + private URL root; + + public void setUp() throws Exception + { + super.setUp(); + root = Thread.currentThread().getContextClassLoader().getResource("repo"); + root = new URL(root.toString() + '/'); + groovyResourceLoader = new DefaultGroovyResourceLoader(root); + } + + public void testLoadGroovySource() throws Exception + { + URL url = groovyResourceLoader.loadGroovySource("MyClass"); + assertNull(url); + File f = new File(new URL(root, "MyClass.groovy").toURI()); + f.createNewFile(); + // Clean up data so that Unit Test can be executed several time + f.deleteOnExit(); + url = groovyResourceLoader.loadGroovySource("MyClass"); + assertNotNull(url); + } +} diff --git a/exo.jcr.component.ext/src/test/java/org/exoplatform/services/rest/ext/groovy/ExtendedClassLoaderTest.java b/exo.jcr.component.ext/src/test/java/org/exoplatform/services/rest/ext/groovy/ExtendedClassLoaderTest.java new file mode 100644 index 0000000000..81342deae3 --- /dev/null +++ b/exo.jcr.component.ext/src/test/java/org/exoplatform/services/rest/ext/groovy/ExtendedClassLoaderTest.java @@ -0,0 +1,76 @@ +/* + * This file is part of the Meeds project (https://meeds.io/). + * Copyright (C) 2020 Meeds Association + * contact@meeds.io + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser 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 + * Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.exoplatform.services.rest.ext.groovy; + +import groovy.lang.GroovyObject; + +import org.exoplatform.services.rest.ext.BaseTest; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Andrey Parfonov + * @version $Id$ + */ +@SuppressWarnings("rawtypes") +public class ExtendedClassLoaderTest extends BaseTest +{ + public void testParseClasses() throws Exception + { + ExtendedGroovyClassLoader loader = new GroovyClassLoaderProvider().getGroovyClassLoader(); + SourceFile[] sources = new SourceFile[2]; + sources[0] = new SourceFile(Thread.currentThread().getContextClassLoader().getResource("GMain1.groovy")); + sources[1] = + new SourceFile(Thread.currentThread().getContextClassLoader().getResource("repo/dependencies/Dep1.groovy")); + Class[] classes = loader.parseClasses(sources); + assertEquals(2, classes.length); + List names = new ArrayList(2); + for (Class c : classes) + names.add(c.getName()); + assertTrue(names.contains("GMain1")); + assertTrue(names.contains("dependencies.Dep1")); + } + + public void testParseClasses2() throws Exception + { + ExtendedGroovyClassLoader loader = + new GroovyClassLoaderProvider().getGroovyClassLoader(new SourceFolder[]{new SourceFolder(Thread + .currentThread().getContextClassLoader().getResource("repo"))}); + SourceFile[] sources = new SourceFile[1]; + sources[0] = new SourceFile(Thread.currentThread().getContextClassLoader().getResource("GMain1.groovy")); + Class[] classes = loader.parseClasses(sources); + assertEquals(1, classes.length); + List names = new ArrayList(1); + for (Class c : classes) + names.add(c.getName()); + assertTrue(names.contains("GMain1")); + } + + public void testParseClassWithDependency() throws Exception + { + ExtendedGroovyClassLoader loader = new GroovyClassLoaderProvider().getGroovyClassLoader(); + SourceFile[] sources = + new SourceFile[]{new SourceFile(Thread.currentThread().getContextClassLoader() + .getResource("repo/dependencies/Dep1.groovy"))}; + Class clazz = + loader.parseClass(Thread.currentThread().getContextClassLoader().getResourceAsStream("GMain1.groovy"), + "GMain1", sources); + assertEquals("GMain1", clazz.getName()); + assertEquals("dependencies.Dep1", ((GroovyObject)clazz.newInstance()).invokeMethod("m0", new Object[0])); + } +} diff --git a/exo.jcr.component.ext/src/test/java/org/exoplatform/services/rest/ext/groovy/GroovyContextParamTest.java b/exo.jcr.component.ext/src/test/java/org/exoplatform/services/rest/ext/groovy/GroovyContextParamTest.java new file mode 100644 index 0000000000..f05fc800d0 --- /dev/null +++ b/exo.jcr.component.ext/src/test/java/org/exoplatform/services/rest/ext/groovy/GroovyContextParamTest.java @@ -0,0 +1,79 @@ +/* + * This file is part of the Meeds project (https://meeds.io/). + * Copyright (C) 2020 Meeds Association + * contact@meeds.io + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser 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 + * Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package org.exoplatform.services.rest.ext.groovy; + +import org.exoplatform.services.rest.ext.BaseTest; +import org.exoplatform.services.rest.impl.ContainerResponse; +import org.exoplatform.services.rest.impl.EnvironmentContext; +import org.exoplatform.services.rest.tools.ByteArrayContainerResponseWriter; +import org.exoplatform.services.test.mock.MockHttpServletRequest; + +import java.io.InputStream; + +import jakarta.servlet.http.HttpServletRequest; + +/** + * @author Andrey Parfonov + * @version $Id: GroovyContextParamTest.java 2647 2010-06-17 08:39:29Z aparfonov + * $ + */ +public class GroovyContextParamTest extends BaseTest +{ + + private InputStream script; + + public void setUp() throws Exception + { + super.setUp(); + script = Thread.currentThread().getContextClassLoader().getResourceAsStream("groovy1.groovy"); + assertNotNull(script); + } + + @Override + public void tearDown() throws Exception + { + groovyPublisher.resources.clear(); + super.tearDown(); + } + + public void testPerRequest() throws Exception + { + assertEquals(0, binder.getSize()); + assertEquals(0, groovyPublisher.resources.size()); + + groovyPublisher.publishPerRequest(script, new BaseResourceId("g1"), null); + + assertEquals(1, binder.getSize()); + assertEquals(1, groovyPublisher.resources.size()); + + ByteArrayContainerResponseWriter writer = new ByteArrayContainerResponseWriter(); + + EnvironmentContext envctx = new EnvironmentContext(); + + HttpServletRequest httpRequest = + new MockHttpServletRequest("http://localhost:8080/context/a/b", null, 0, "GET", null); + envctx.put(HttpServletRequest.class, httpRequest); + + ContainerResponse resp = + launcher.service("GET", "http://localhost:8080/context/a/b", "http://localhost:8080/context", null, null, + writer, envctx); + assertEquals(200, resp.getStatus()); + assertEquals("GET\n/context/a/b", new String(writer.getBody())); + } + +} diff --git a/exo.jcr.component.ext/src/test/java/org/exoplatform/services/rest/ext/groovy/GroovyDependenciesTest.java b/exo.jcr.component.ext/src/test/java/org/exoplatform/services/rest/ext/groovy/GroovyDependenciesTest.java new file mode 100644 index 0000000000..252ad55ea7 --- /dev/null +++ b/exo.jcr.component.ext/src/test/java/org/exoplatform/services/rest/ext/groovy/GroovyDependenciesTest.java @@ -0,0 +1,62 @@ +/* + * This file is part of the Meeds project (https://meeds.io/). + * Copyright (C) 2020 Meeds Association + * contact@meeds.io + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser 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 + * Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package org.exoplatform.services.rest.ext.groovy; + +import org.exoplatform.services.rest.ext.BaseTest; +import org.exoplatform.services.rest.impl.ContainerResponse; +import org.exoplatform.services.rest.tools.ByteArrayContainerResponseWriter; + +import java.io.InputStream; +import java.net.URL; + +/** + * @author Andrey Parfonov + * @version $Id$ + */ +public class GroovyDependenciesTest extends BaseTest +{ + private InputStream script; + + @Override + public void setUp() throws Exception + { + super.setUp(); + URL root = Thread.currentThread().getContextClassLoader().getResource("repo"); + DefaultGroovyResourceLoader groovyResourceLoader = new DefaultGroovyResourceLoader(root); + groovyPublisher.getGroovyClassLoader().setResourceLoader(groovyResourceLoader); + + script = Thread.currentThread().getContextClassLoader().getResourceAsStream("GMain1.groovy"); + assertNotNull(script); + } + + public void testDependency() throws Exception + { + groovyPublisher.publishPerRequest(script, new BaseResourceId("GMain1"), null); + ByteArrayContainerResponseWriter writer = new ByteArrayContainerResponseWriter(); + ContainerResponse resp = launcher.service("GET", "/a", "", null, null, writer, null); + assertEquals(200, resp.getStatus()); + assertEquals("dependencies.Dep1", new String(writer.getBody())); + } + + @Override + public void tearDown() throws Exception + { + groovyPublisher.resources.clear(); + super.tearDown(); + } +} diff --git a/exo.jcr.component.ext/src/test/java/org/exoplatform/services/rest/ext/groovy/GroovyExoComponentTest.java b/exo.jcr.component.ext/src/test/java/org/exoplatform/services/rest/ext/groovy/GroovyExoComponentTest.java new file mode 100644 index 0000000000..37914e79c2 --- /dev/null +++ b/exo.jcr.component.ext/src/test/java/org/exoplatform/services/rest/ext/groovy/GroovyExoComponentTest.java @@ -0,0 +1,89 @@ +/* + * This file is part of the Meeds project (https://meeds.io/). + * Copyright (C) 2020 Meeds Association + * contact@meeds.io + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser 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 + * Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package org.exoplatform.services.rest.ext.groovy; + +import org.exoplatform.services.rest.ext.BaseTest; +import org.exoplatform.services.rest.impl.ContainerResponse; +import org.exoplatform.services.rest.tools.ByteArrayContainerResponseWriter; + +import java.io.InputStream; + +/** + * @author Andrey Parfonov + * @version $Id$ + */ +public class GroovyExoComponentTest extends BaseTest +{ + + private InputStream script; + + @Override + public void setUp() throws Exception + { + super.setUp(); + container.registerComponentInstance(Component1.class.getName(), new Component1()); + script = Thread.currentThread().getContextClassLoader().getResourceAsStream("groovy2.groovy"); + assertNotNull(script); + } + + @Override + public void tearDown() throws Exception + { + container.unregisterComponent(Component1.class.getName()); + groovyPublisher.resources.clear(); + super.tearDown(); + } + + public void testExoComponentPerRequest() throws Exception + { + containerComponentTest(false, new BaseResourceId("g1")); + } + + public void testExoComponentSingleton() throws Exception + { + containerComponentTest(true, new BaseResourceId("g2")); + } + + private void containerComponentTest(boolean singleton, ResourceId resourceId) throws Exception + { + assertEquals(0, binder.getSize()); + assertEquals(0, groovyPublisher.resources.size()); + + if (singleton) + groovyPublisher.publishSingleton(script, resourceId, null); + else + groovyPublisher.publishPerRequest(script, resourceId, null); + + assertEquals(1, binder.getSize()); + assertEquals(1, groovyPublisher.resources.size()); + + ByteArrayContainerResponseWriter writer = new ByteArrayContainerResponseWriter(); + ContainerResponse resp = launcher.service("GET", "/a/b", "", null, null, writer, null); + assertEquals(200, resp.getStatus()); + assertEquals("exo container's component", new String(writer.getBody())); + } + + public static class Component1 + { + public String getName() + { + return "exo container's component"; + } + } + +} diff --git a/exo.jcr.component.ext/src/test/java/org/exoplatform/services/rest/ext/groovy/GroovySimpleTest.java b/exo.jcr.component.ext/src/test/java/org/exoplatform/services/rest/ext/groovy/GroovySimpleTest.java new file mode 100644 index 0000000000..3b04bdaae2 --- /dev/null +++ b/exo.jcr.component.ext/src/test/java/org/exoplatform/services/rest/ext/groovy/GroovySimpleTest.java @@ -0,0 +1,85 @@ +/* + * This file is part of the Meeds project (https://meeds.io/). + * Copyright (C) 2020 Meeds Association + * contact@meeds.io + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser 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 + * Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package org.exoplatform.services.rest.ext.groovy; + +import org.exoplatform.services.rest.ext.BaseTest; +import org.exoplatform.services.rest.impl.ContainerResponse; +import org.exoplatform.services.rest.tools.ByteArrayContainerResponseWriter; + +/** + * @author Andrey Parfonov + * @version $Id$ + */ +public class GroovySimpleTest extends BaseTest +{ + + @Override + public void tearDown() throws Exception + { + groovyPublisher.resources.clear(); + super.tearDown(); + } + + public void testPerRequest() throws Exception + { + publicationTest(false, new BaseResourceId("g1")); + } + + public void testSingleton() throws Exception + { + publicationTest(true, new BaseResourceId("g2")); + } + + private void publicationTest(boolean singleton, ResourceId resourceId) throws Exception + { + String script = // + "@javax.ws.rs.Path(\"a\")" // + + "class GroovyResource {" // + + "@javax.ws.rs.GET @javax.ws.rs.Path(\"{who}\")" // + + "def m0(@javax.ws.rs.PathParam(\"who\") String who) { return (\"hello \" + who)}" // + + "}"; + + assertEquals(0, binder.getSize()); + assertEquals(0, groovyPublisher.resources.size()); + + if (singleton) + groovyPublisher.publishSingleton(script, resourceId, null); + else + groovyPublisher.publishPerRequest(script, resourceId, null); + + assertEquals(1, binder.getSize()); + assertEquals(1, groovyPublisher.resources.size()); + assertTrue(groovyPublisher.isPublished(resourceId)); + + String cs = + binder.getResources().get(0).getObjectModel().getObjectClass().getProtectionDomain().getCodeSource() + .getLocation().toString(); + assertEquals("file:/groovy/script/jaxrs", cs); + + ByteArrayContainerResponseWriter writer = new ByteArrayContainerResponseWriter(); + ContainerResponse resp = launcher.service("GET", "/a/groovy", "", null, null, writer, null); + assertEquals(200, resp.getStatus()); + assertEquals("hello groovy", new String(writer.getBody())); + + groovyPublisher.unpublishResource(resourceId); + + assertEquals(0, binder.getSize()); + assertEquals(0, groovyPublisher.resources.size()); + } + +} diff --git a/exo.jcr.component.ext/src/test/java/org/exoplatform/services/script/groovy/Book.java b/exo.jcr.component.ext/src/test/java/org/exoplatform/services/script/groovy/Book.java new file mode 100644 index 0000000000..4eced2629f --- /dev/null +++ b/exo.jcr.component.ext/src/test/java/org/exoplatform/services/script/groovy/Book.java @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2009 eXo Platform SAS. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.exoplatform.services.script.groovy; + +/** + * @author Andrey Parfonov + * @version $Id: $ + */ +public class Book +{ + + private String title = "Groovy in Action"; + + private String author = "Andrew Glover"; + + private float price = 20.10F; + + private String isdn = "1234567890987654321"; + + public String getTitle() + { + return title; + } + + public void setTitle(String title) + { + this.title = title; + } + + public String getAuthor() + { + return author; + } + + public void setAuthor(String author) + { + this.author = author; + } + + public float getPrice() + { + return price; + } + + public void setPrice(float price) + { + this.price = price; + } + + public String getIsdn() + { + return isdn; + } + + public void setIsdn(String isdn) + { + this.isdn = isdn; + } + +} diff --git a/exo.jcr.component.ext/src/test/java/org/exoplatform/services/script/groovy/GroovyInstantiatorTest.java b/exo.jcr.component.ext/src/test/java/org/exoplatform/services/script/groovy/GroovyInstantiatorTest.java new file mode 100644 index 0000000000..314f1e73a7 --- /dev/null +++ b/exo.jcr.component.ext/src/test/java/org/exoplatform/services/script/groovy/GroovyInstantiatorTest.java @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2009 eXo Platform SAS. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.exoplatform.services.script.groovy; + +import b.ImportedClass; +import groovy.lang.GroovyObject; +import junit.framework.TestCase; + +import org.exoplatform.container.ExoContainer; +import org.exoplatform.container.StandaloneContainer; + +/** + * @author Andrey Parfonov + * @version $Id: $ + */ +public class GroovyInstantiatorTest extends TestCase +{ + + private GroovyScriptInstantiator groovyScriptInstantiator; + + private GroovyScriptInstantiator jarjarGroovyScriptInstantiator; + + /* + * (non-Javadoc) + * @see junit.framework.TestCase#setUp() + */ + @Override + public void setUp() throws Exception + { + StandaloneContainer.setConfigurationPath("src/test/resources/conf/standalone/test-configuration.xml"); + ExoContainer container = StandaloneContainer.getInstance(); + groovyScriptInstantiator = + (GroovyScriptInstantiator)container.getComponentInstance(GroovyScriptInstantiator.class); + jarjarGroovyScriptInstantiator = + (GroovyScriptInstantiator)container.getComponentInstance("JarJarGroovyScriptInstantiator"); + assertNotNull(groovyScriptInstantiator); + assertNotNull(jarjarGroovyScriptInstantiator); + } + + public void testGroovyScriptInstantiatorSimple() throws Exception + { + String url = Thread.currentThread().getContextClassLoader().getResource("Book.groovy").toString(); + GroovyObject groovyObject = (GroovyObject)groovyScriptInstantiator.instantiateScript(url); + /* + * --- Groovy code --- def title = "Groovy in Action" def author = + * "Andrew Glover" def price = 20.10 def isdn = "1234567890987654321" + */ + assertEquals("Andrew Glover", groovyObject.getProperty("author")); + assertEquals("Groovy in Action", groovyObject.getProperty("title")); + assertEquals("1234567890987654321", groovyObject.getProperty("isdn")); + assertEquals(20, groovyObject.getProperty("price")); + groovyObject.setProperty("price", 10); + assertEquals(10, groovyObject.getProperty("price")); + } + + public void testGroovyScriptInstantiatorInjection() throws Exception + { + String url = Thread.currentThread().getContextClassLoader().getResource("TestInjection.groovy").toString(); + GroovyObject groovyObject = (GroovyObject)groovyScriptInstantiator.instantiateScript(url); + assertNotNull(groovyObject.getProperty("sampleComponent")); + assertEquals("sample component", ((SampleComponent)groovyObject.getProperty("sampleComponent")).getAbout()); + } + + public void testGroovyScriptInstantiatorXML() throws Exception + { + String url = + Thread.currentThread().getContextClassLoader().getResource("TestSimpleXMLGenerator.groovy").toString(); + GroovyObject groovyObject = (GroovyObject)groovyScriptInstantiator.instantiateScript(url); + groovyObject.invokeMethod("generateXML", new Object[]{new Book()}); + } + + public void testGroovyScriptJarJar() throws Exception + { + String url = Thread.currentThread().getContextClassLoader().getResource("TestJarJar.groovy").toString(); + GroovyObject groovyObject = (GroovyObject)jarjarGroovyScriptInstantiator.instantiateScript(url); + Object field = groovyObject.getProperty("field"); + assertNotNull(field); + assertTrue("Was expecting object " + field + " to be an instance of class " + ImportedClass.class.getName() + + "instead of class " + field.getClass().getName(), field instanceof ImportedClass); + } +} diff --git a/exo.jcr.component.ext/src/test/java/org/exoplatform/services/script/groovy/SampleComponent.java b/exo.jcr.component.ext/src/test/java/org/exoplatform/services/script/groovy/SampleComponent.java new file mode 100644 index 0000000000..babb1d9213 --- /dev/null +++ b/exo.jcr.component.ext/src/test/java/org/exoplatform/services/script/groovy/SampleComponent.java @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2009 eXo Platform SAS. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.exoplatform.services.script.groovy; + +/** + * @author Andrey Parfonov + * @version $Id: $ + */ +public class SampleComponent +{ + + // nothing to do, it must be injected it constructor of Groovy script + + private String about = "sample component"; + + public String getAbout() + { + return about; + } + + public void setAbout(String about) + { + this.about = about; + } + +} diff --git a/exo.jcr.component.ext/src/test/java/org/exoplatform/services/script/groovy/jarjar/JarJarTest.java b/exo.jcr.component.ext/src/test/java/org/exoplatform/services/script/groovy/jarjar/JarJarTest.java new file mode 100644 index 0000000000..cfcf818a38 --- /dev/null +++ b/exo.jcr.component.ext/src/test/java/org/exoplatform/services/script/groovy/jarjar/JarJarTest.java @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2009 eXo Platform SAS. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.exoplatform.services.script.groovy.jarjar; + +import junit.framework.AssertionFailedError; +import junit.framework.TestCase; + +/** + * @author Julien Viet + * @version $Revision$ + */ +public class JarJarTest extends TestCase +{ + + public static AssertionFailedError error = null; + + public JarJarTest() + { + } + + public JarJarTest(String s) + { + super(s); + } + + private void testTop(TestScript script) + { + Mapping m1 = new Mapping(); + m1.addMapping("a", "b"); + Mapping m2 = new Mapping(); + m2.addMapping("a", "prefix1.a"); + + // Transform a top package into a top package + assertEquals("b", script.execute(m1)); + + // Transform a top package into a prefixed package + assertEquals("prefix1.a", script.execute(m2)); + } + + public void testTopClassLitteral() throws Exception + { + testTop(new TestScript("classlitteral1.groovy")); + testTop(new TestScript("classlitteral_1.groovy")); + testTop(new TestScript("import1.groovy")); + } + + private void testPrefix(TestScript script) throws Exception + { + Mapping m1 = new Mapping(); + m1.addMapping("prefix1", "prefix2"); + Mapping m2 = new Mapping(); + m2.addMapping("prefix1.a", "a"); + Mapping m3 = new Mapping(); + m3.addMapping("prefix1.a", "prefix2.b"); + Mapping m4 = new Mapping(); + m4.addMapping("prefix1.a", "prefix1.b"); + + // Transform the top package prefix + assertEquals("prefix2.a", script.execute(m1)); + + // Transform the full prefixed package + assertEquals("a", script.execute(m2)); + + // Transform the full prefixed package + assertEquals("prefix2.b", script.execute(m3)); + + // Transform the full prefixed package + assertEquals("prefix1.b", script.execute(m4)); + } + + public void testPrefixClassLitteral() throws Exception + { + testPrefix(new TestScript("classlitteral2.groovy")); + testPrefix(new TestScript("classlitteral_2.groovy")); + testPrefix(new TestScript("import2.groovy")); + } +} diff --git a/exo.jcr.component.ext/src/test/java/org/exoplatform/services/script/groovy/jarjar/Mapping.java b/exo.jcr.component.ext/src/test/java/org/exoplatform/services/script/groovy/jarjar/Mapping.java new file mode 100644 index 0000000000..e54f7d606d --- /dev/null +++ b/exo.jcr.component.ext/src/test/java/org/exoplatform/services/script/groovy/jarjar/Mapping.java @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2009 eXo Platform SAS. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.exoplatform.services.script.groovy.jarjar; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author Julien Viet + * @version $Revision$ + */ +public class Mapping +{ + + /** . */ + private final Map, List> map; + + public Mapping() + { + map = new HashMap, List>(); + } + + public void addMapping(String source, String destination) + { + List sourcePackage = Arrays.asList(source.split("\\.")); + List destinationPackage = Arrays.asList(destination.split("\\.")); + map.put(sourcePackage, destinationPackage); + } + + public void configure(JarJarClassLoader loader) + { + for (Map.Entry, List> entry : map.entrySet()) + { + loader.addMapping(entry.getKey(), entry.getValue()); + } + } +} diff --git a/exo.jcr.component.ext/src/test/java/org/exoplatform/services/script/groovy/jarjar/TestScript.java b/exo.jcr.component.ext/src/test/java/org/exoplatform/services/script/groovy/jarjar/TestScript.java new file mode 100644 index 0000000000..03dc5fab5f --- /dev/null +++ b/exo.jcr.component.ext/src/test/java/org/exoplatform/services/script/groovy/jarjar/TestScript.java @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2009 eXo Platform SAS. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.exoplatform.services.script.groovy.jarjar; + +import groovy.lang.GroovyCodeSource; +import groovy.lang.GroovyObject; +import junit.framework.Assert; +import junit.framework.AssertionFailedError; + +import java.io.IOException; +import java.net.URL; + +/** + * @author Julien Viet + * @version $Revision$ + */ +public class TestScript +{ + + /** . */ + private final String name; + + public TestScript(String name) + { + this.name = name; + } + + public Object execute(Mapping mapping) + { + + // + JarJarClassLoader loader = + JarJarClassLoader.createJarJarClassLoaderInPrivilegedMode(Thread.currentThread().getContextClassLoader()); + + // + mapping.configure(loader); + + // Obtain script class + URL url = Thread.currentThread().getContextClassLoader().getResource("jarjar/" + name); + Assert.assertNotNull(url); + GroovyCodeSource gcs; + try + { + gcs = new GroovyCodeSource(url); + } + catch (Exception e) + { + AssertionFailedError err = new AssertionFailedError(); + err.initCause(e); + throw err; + } + + Class testClass = loader.parseClass(gcs);; + + // Instantiate script + GroovyObject testObject; + try + { + testObject = (GroovyObject)testClass.newInstance(); + } + catch (Exception e) + { + AssertionFailedError err = new AssertionFailedError(); + err.initCause(e); + throw err; + } + + // Invoke finally + return testObject.invokeMethod("run", new Object[0]); + } +} diff --git a/exo.jcr.component.ext/src/test/java/prefix1/a/ClassLitteral.java b/exo.jcr.component.ext/src/test/java/prefix1/a/ClassLitteral.java new file mode 100644 index 0000000000..9b4f68ba37 --- /dev/null +++ b/exo.jcr.component.ext/src/test/java/prefix1/a/ClassLitteral.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2009 eXo Platform SAS. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package prefix1.a; + +/** + * @author Julien Viet + * @version $Revision$ + */ +public class ClassLitteral +{ + + public static String getValue() + { + return "prefix1.a"; + } +} \ No newline at end of file diff --git a/exo.jcr.component.ext/src/test/java/prefix1/a/ImportedClass.java b/exo.jcr.component.ext/src/test/java/prefix1/a/ImportedClass.java new file mode 100644 index 0000000000..b958f12214 --- /dev/null +++ b/exo.jcr.component.ext/src/test/java/prefix1/a/ImportedClass.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2009 eXo Platform SAS. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package prefix1.a; + +/** + * @author Julien Viet + * @version $Revision$ + */ +public class ImportedClass +{ + + public String getValue() + { + return "prefix1.a"; + } +} \ No newline at end of file diff --git a/exo.jcr.component.ext/src/test/java/prefix1/b/ClassLitteral.java b/exo.jcr.component.ext/src/test/java/prefix1/b/ClassLitteral.java new file mode 100644 index 0000000000..129baa64bf --- /dev/null +++ b/exo.jcr.component.ext/src/test/java/prefix1/b/ClassLitteral.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2009 eXo Platform SAS. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package prefix1.b; + +/** + * @author Julien Viet + * @version $Revision$ + */ +public class ClassLitteral +{ + + public static String getValue() + { + return "prefix1.b"; + } +} \ No newline at end of file diff --git a/exo.jcr.component.ext/src/test/java/prefix1/b/ImportedClass.java b/exo.jcr.component.ext/src/test/java/prefix1/b/ImportedClass.java new file mode 100644 index 0000000000..dff145b1a4 --- /dev/null +++ b/exo.jcr.component.ext/src/test/java/prefix1/b/ImportedClass.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2009 eXo Platform SAS. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package prefix1.b; + +/** + * @author Julien Viet + * @version $Revision$ + */ +public class ImportedClass +{ + + public String getValue() + { + return "prefix1.b"; + } +} \ No newline at end of file diff --git a/exo.jcr.component.ext/src/test/java/prefix2/a/ClassLitteral.java b/exo.jcr.component.ext/src/test/java/prefix2/a/ClassLitteral.java new file mode 100644 index 0000000000..e761b5864d --- /dev/null +++ b/exo.jcr.component.ext/src/test/java/prefix2/a/ClassLitteral.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2009 eXo Platform SAS. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package prefix2.a; + +/** + * @author Julien Viet + * @version $Revision$ + */ +public class ClassLitteral +{ + + public static String getValue() + { + return "prefix2.a"; + } +} \ No newline at end of file diff --git a/exo.jcr.component.ext/src/test/java/prefix2/a/ImportedClass.java b/exo.jcr.component.ext/src/test/java/prefix2/a/ImportedClass.java new file mode 100644 index 0000000000..ea042fad8e --- /dev/null +++ b/exo.jcr.component.ext/src/test/java/prefix2/a/ImportedClass.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2009 eXo Platform SAS. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package prefix2.a; + +/** + * @author Julien Viet + * @version $Revision$ + */ +public class ImportedClass +{ + + public String getValue() + { + return "prefix2.a"; + } +} \ No newline at end of file diff --git a/exo.jcr.component.ext/src/test/java/prefix2/b/ClassLitteral.java b/exo.jcr.component.ext/src/test/java/prefix2/b/ClassLitteral.java new file mode 100644 index 0000000000..0d58a6b1a3 --- /dev/null +++ b/exo.jcr.component.ext/src/test/java/prefix2/b/ClassLitteral.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2009 eXo Platform SAS. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package prefix2.b; + +/** + * @author Julien Viet + * @version $Revision$ + */ +public class ClassLitteral +{ + + public static String getValue() + { + return "prefix2.b"; + } +} \ No newline at end of file diff --git a/exo.jcr.component.ext/src/test/java/prefix2/b/ImportedClass.java b/exo.jcr.component.ext/src/test/java/prefix2/b/ImportedClass.java new file mode 100644 index 0000000000..73bea2a76d --- /dev/null +++ b/exo.jcr.component.ext/src/test/java/prefix2/b/ImportedClass.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2009 eXo Platform SAS. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package prefix2.b; + +/** + * @author Julien Viet + * @version $Revision$ + */ +public class ImportedClass +{ + + public String getValue() + { + return "prefix2.b"; + } +} \ No newline at end of file diff --git a/exo.jcr.component.ext/src/test/resources/Book.groovy b/exo.jcr.component.ext/src/test/resources/Book.groovy new file mode 100644 index 0000000000..66e365fca0 --- /dev/null +++ b/exo.jcr.component.ext/src/test/resources/Book.groovy @@ -0,0 +1,8 @@ +package org.exoplatform.script.groovy.test + +class Book { + def title = "Groovy in Action" + def author = "Andrew Glover" + def price = 20 + def isdn = "1234567890987654321" +} \ No newline at end of file diff --git a/exo.jcr.component.ext/src/test/resources/TestInjection.groovy b/exo.jcr.component.ext/src/test/resources/TestInjection.groovy new file mode 100644 index 0000000000..efda0172fa --- /dev/null +++ b/exo.jcr.component.ext/src/test/resources/TestInjection.groovy @@ -0,0 +1,12 @@ +package org.exoplatform.script.groovy.test + +public class TestInjection { + + def org.exoplatform.services.script.groovy.SampleComponent sampleComponent + + // Object in constructor must be in container + public TestInjection(org.exoplatform.services.script.groovy.SampleComponent sampleComponent) { + this.sampleComponent = sampleComponent; + } + +} \ No newline at end of file diff --git a/exo.jcr.component.ext/src/test/resources/TestJarJar.groovy b/exo.jcr.component.ext/src/test/resources/TestJarJar.groovy new file mode 100644 index 0000000000..ba3866faad --- /dev/null +++ b/exo.jcr.component.ext/src/test/resources/TestJarJar.groovy @@ -0,0 +1,13 @@ +package org.exoplatform.script.groovy.test + +import a.ImportedClass + +public class TestJarJar { + + def ImportedClass field = new ImportedClass(); + + // Object in constructor must be in container + public TestInjection() { + } + +} \ No newline at end of file diff --git a/exo.jcr.component.ext/src/test/resources/TestSimpleXMLGenerator.groovy b/exo.jcr.component.ext/src/test/resources/TestSimpleXMLGenerator.groovy new file mode 100644 index 0000000000..f675807371 --- /dev/null +++ b/exo.jcr.component.ext/src/test/resources/TestSimpleXMLGenerator.groovy @@ -0,0 +1,18 @@ +package org.exoplatform.script.groovy.test + +import groovy.xml.MarkupBuilder +import org.exoplatform.services.script.groovy.Book +public class SimpleXMLGenerator { + + public void generateXML (Book b) { + def xmlBuilder = new MarkupBuilder() + xmlBuilder.books() { + book() { + title(b.getTitle()) + author(b.getAuthor()) + price(b.getPrice()) + ISDN(b.getIsdn()) + } + } + } +} \ No newline at end of file diff --git a/exo.jcr.component.ext/src/test/resources/conf/standalone/test-configuration.xml b/exo.jcr.component.ext/src/test/resources/conf/standalone/test-configuration.xml index 09b7046d57..5ebdccc457 100644 --- a/exo.jcr.component.ext/src/test/resources/conf/standalone/test-configuration.xml +++ b/exo.jcr.component.ext/src/test/resources/conf/standalone/test-configuration.xml @@ -37,6 +37,32 @@ + + org.exoplatform.services.script.groovy.SampleComponent + + + + org.exoplatform.services.script.groovy.GroovyScriptInstantiator + + + + JarJarGroovyScriptInstantiator + org.exoplatform.services.script.groovy.GroovyScriptInstantiator + + + jarjar.mapping + addPlugin + org.exoplatform.services.script.groovy.GroovyScriptJarJarPlugin + + + mapping + a->b + + + + + + org.exoplatform.services.jcr.RepositoryService org.exoplatform.services.jcr.impl.RepositoryServiceImpl diff --git a/exo.jcr.component.ext/src/test/resources/jarjar/classlitteral1.groovy b/exo.jcr.component.ext/src/test/resources/jarjar/classlitteral1.groovy new file mode 100644 index 0000000000..c5befe9c48 --- /dev/null +++ b/exo.jcr.component.ext/src/test/resources/jarjar/classlitteral1.groovy @@ -0,0 +1,2 @@ +def value = a.ClassLitteral.class.getValue(); +return value; \ No newline at end of file diff --git a/exo.jcr.component.ext/src/test/resources/jarjar/classlitteral2.groovy b/exo.jcr.component.ext/src/test/resources/jarjar/classlitteral2.groovy new file mode 100644 index 0000000000..06d1cbeacf --- /dev/null +++ b/exo.jcr.component.ext/src/test/resources/jarjar/classlitteral2.groovy @@ -0,0 +1,2 @@ +def value = prefix1.a.ClassLitteral.class.getValue(); +return value; \ No newline at end of file diff --git a/exo.jcr.component.ext/src/test/resources/jarjar/classlitteral_1.groovy b/exo.jcr.component.ext/src/test/resources/jarjar/classlitteral_1.groovy new file mode 100644 index 0000000000..2d2e8321af --- /dev/null +++ b/exo.jcr.component.ext/src/test/resources/jarjar/classlitteral_1.groovy @@ -0,0 +1,2 @@ +def value = a.ClassLitteral.getValue(); +return value; \ No newline at end of file diff --git a/exo.jcr.component.ext/src/test/resources/jarjar/classlitteral_2.groovy b/exo.jcr.component.ext/src/test/resources/jarjar/classlitteral_2.groovy new file mode 100644 index 0000000000..66d982a163 --- /dev/null +++ b/exo.jcr.component.ext/src/test/resources/jarjar/classlitteral_2.groovy @@ -0,0 +1,2 @@ +def value = prefix1.a.ClassLitteral.getValue(); +return value; \ No newline at end of file diff --git a/exo.jcr.component.ext/src/test/resources/jarjar/import1.groovy b/exo.jcr.component.ext/src/test/resources/jarjar/import1.groovy new file mode 100644 index 0000000000..741ac8e7ad --- /dev/null +++ b/exo.jcr.component.ext/src/test/resources/jarjar/import1.groovy @@ -0,0 +1,3 @@ +import a.ImportedClass; +def value = new ImportedClass().getValue(); +return value; \ No newline at end of file diff --git a/exo.jcr.component.ext/src/test/resources/jarjar/import2.groovy b/exo.jcr.component.ext/src/test/resources/jarjar/import2.groovy new file mode 100644 index 0000000000..7d1b72f0d0 --- /dev/null +++ b/exo.jcr.component.ext/src/test/resources/jarjar/import2.groovy @@ -0,0 +1,3 @@ +import prefix1.a.ImportedClass; +def value = new ImportedClass().getValue(); +return value; \ No newline at end of file diff --git a/exo.jcr.component.webdav/pom.xml b/exo.jcr.component.webdav/pom.xml index f826a62a75..5f46f4083e 100644 --- a/exo.jcr.component.webdav/pom.xml +++ b/exo.jcr.component.webdav/pom.xml @@ -31,7 +31,7 @@ eXo PLF:: JCR :: Component :: Webdav Service Implementation of Webdav Service of Exoplatform SAS 'eXo JCR' project. - 0.56 + 0.53 @@ -50,6 +50,14 @@ + + + src/test/resources + + ** + + + org.apache.maven.plugins @@ -94,13 +102,6 @@ - - - ant - ant-optional - 1.5.3-1 - - diff --git a/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/provider/XSLTStreamingOutput.java b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/provider/XSLTStreamingOutput.java new file mode 100644 index 0000000000..9c5e237b31 --- /dev/null +++ b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/provider/XSLTStreamingOutput.java @@ -0,0 +1,136 @@ +/* + * This file is part of the Meeds project (https://meeds.io/). + * Copyright (C) 2020 Meeds Association + * contact@meeds.io + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser 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 + * Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.exoplatform.services.rest.ext.provider; + +import org.exoplatform.container.ExoContainer; +import org.exoplatform.container.ExoContainerContext; +import org.exoplatform.services.xml.transform.NotSupportedIOTypeException; +import org.exoplatform.services.xml.transform.impl.trax.TRAXTemplatesServiceImpl; +import org.exoplatform.services.xml.transform.trax.TRAXTemplates; +import org.exoplatform.services.xml.transform.trax.TRAXTemplatesService; +import org.exoplatform.services.xml.transform.trax.TRAXTransformer; + +import java.io.IOException; +import java.io.OutputStream; +import java.util.Map; + +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.StreamingOutput; +import javax.xml.transform.Source; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.transform.stream.StreamResult; + +/** + * This type should be used by resource methods when need to apply XSLT + * transformation for returned {@link Source}. + * + * @see StreamingOutput + * @author Dmytro Katayev + * @version $Id: XLSTStreamingOutPut.java + */ +public class XSLTStreamingOutput implements StreamingOutput +{ + + private String schemeName; + + private Source source; + + private Map xsltParams; + + /** + * XSLTStreamingOutput constructor. + * + * @param schemeName XLST scheme name. Must be registered in + * {@link org.exoplatform.services.xml.transform.impl.trax.TRAXTemplatesLoaderPlugin + * TRAXTemplatesLoaderPlugin } + * @param source entity to write into output stream. + */ + public XSLTStreamingOutput(String schemeName, Source source) + { + this.schemeName = schemeName; + this.source = source; + } + + /** + * XSLTStreamingOutput constructor. + * + * @param schemeName XLST scheme name. Must be registered in + * {@link org.exoplatform.services.xml.transform.impl.trax.TRAXTemplatesLoaderPlugin + * TRAXTemplatesLoaderPlugin } + * @param source entity to write into output stream. + * @param xsltParams XSLT parameters + */ + public XSLTStreamingOutput(String schemeName, Source source, Map xsltParams) + { + this(schemeName, source); + this.xsltParams = xsltParams; + } + + /** + * {@inheritDoc} . + */ + public void write(OutputStream outStream) throws IOException, WebApplicationException + { + + ExoContainer container = ExoContainerContext.getCurrentContainer(); + + TRAXTemplatesService templatesService = + (TRAXTemplatesService)container.getComponentInstanceOfType(TRAXTemplatesServiceImpl.class); + + try + { + TRAXTransformer transformer = null; + if (schemeName != null) + { + TRAXTemplates t = templatesService.getTemplates(schemeName); + if (t == null) + { + String msg = "Template " + schemeName + " not found."; + throw new IllegalArgumentException(msg); + } + transformer = t.newTransformer(); + } + else + { + throw new IllegalArgumentException("XSLT scheme name is null."); + } + transformer.initResult(new StreamResult(outStream)); + if (xsltParams != null) + { + for (Map.Entry e : xsltParams.entrySet()) + { + transformer.setParameter(e.getKey(), e.getValue()); + } + } + transformer.transform(source); + } + catch (TransformerConfigurationException tce) + { + throw new IOException("Can't write to output stream " + tce, tce); + } + catch (NotSupportedIOTypeException nse) + { + throw new IOException("Can't write to output stream " + nse, nse); + } + catch (TransformerException tre) + { + throw new IOException("Can't write to output stream " + tre, tre); + } + } + +} diff --git a/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/webdav/method/ACL.java b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/webdav/method/ACL.java new file mode 100644 index 0000000000..4f27239b16 --- /dev/null +++ b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/webdav/method/ACL.java @@ -0,0 +1,41 @@ +/* + * This file is part of the Meeds project (https://meeds.io/). + * Copyright (C) 2020 Meeds Association + * contact@meeds.io + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser 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 + * Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +package org.exoplatform.services.rest.ext.webdav.method; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import javax.ws.rs.HttpMethod; + +/** + * + * Created by The eXo Platform SAS . + * + * @author Vitaliy Gulyy + * @version $ + */ + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@HttpMethod("ACL") +public @interface ACL { + +} diff --git a/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/webdav/method/CHECKIN.java b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/webdav/method/CHECKIN.java new file mode 100644 index 0000000000..185965578a --- /dev/null +++ b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/webdav/method/CHECKIN.java @@ -0,0 +1,36 @@ +/* + * This file is part of the Meeds project (https://meeds.io/). + * Copyright (C) 2020 Meeds Association + * contact@meeds.io + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser 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 + * Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.exoplatform.services.rest.ext.webdav.method; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import javax.ws.rs.HttpMethod; + +/** + * Created by The eXo Platform SAS. + * @author Dmytro Katayev + * 22 Oct 2008 + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@HttpMethod("CHECKIN") +public @interface CHECKIN { + +} diff --git a/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/webdav/method/CHECKOUT.java b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/webdav/method/CHECKOUT.java new file mode 100644 index 0000000000..c7e63791c7 --- /dev/null +++ b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/webdav/method/CHECKOUT.java @@ -0,0 +1,37 @@ +/* + * This file is part of the Meeds project (https://meeds.io/). + * Copyright (C) 2020 Meeds Association + * contact@meeds.io + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser 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 + * Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.exoplatform.services.rest.ext.webdav.method; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import javax.ws.rs.HttpMethod; + +/** + * Created by The eXo Platform SAS. + * @author Dmytro Katayev + * 22 Oct 2008 + */ + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@HttpMethod("CHECKOUT") +public @interface CHECKOUT { + +} diff --git a/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/webdav/method/COPY.java b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/webdav/method/COPY.java new file mode 100644 index 0000000000..cb7f6ee278 --- /dev/null +++ b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/webdav/method/COPY.java @@ -0,0 +1,36 @@ +/* + * This file is part of the Meeds project (https://meeds.io/). + * Copyright (C) 2020 Meeds Association + * contact@meeds.io + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser 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 + * Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.exoplatform.services.rest.ext.webdav.method; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import javax.ws.rs.HttpMethod; + +/** + * Created by The eXo Platform SAS. + * @author Dmytro Katayev + * 22 Oct 2008 + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@HttpMethod("COPY") +public @interface COPY { + +} diff --git a/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/webdav/method/LOCK.java b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/webdav/method/LOCK.java new file mode 100644 index 0000000000..4cf7251bd5 --- /dev/null +++ b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/webdav/method/LOCK.java @@ -0,0 +1,36 @@ +/* + * This file is part of the Meeds project (https://meeds.io/). + * Copyright (C) 2020 Meeds Association + * contact@meeds.io + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser 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 + * Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.exoplatform.services.rest.ext.webdav.method; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import javax.ws.rs.HttpMethod; + +/** + * Created by The eXo Platform SAS. + * @author Dmytro Katayev + * 22 Oct 2008 + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@HttpMethod("LOCK") +public @interface LOCK { + +} diff --git a/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/webdav/method/MKCOL.java b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/webdav/method/MKCOL.java new file mode 100644 index 0000000000..b7823df2b7 --- /dev/null +++ b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/webdav/method/MKCOL.java @@ -0,0 +1,36 @@ +/* + * This file is part of the Meeds project (https://meeds.io/). + * Copyright (C) 2020 Meeds Association + * contact@meeds.io + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser 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 + * Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.exoplatform.services.rest.ext.webdav.method; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import javax.ws.rs.HttpMethod; + +/** + * Created by The eXo Platform SAS. + * @author Dmytro Katayev + * 22 Oct 2008 + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@HttpMethod("MKCOL") +public @interface MKCOL { + +} diff --git a/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/webdav/method/MOVE.java b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/webdav/method/MOVE.java new file mode 100644 index 0000000000..3f31479869 --- /dev/null +++ b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/webdav/method/MOVE.java @@ -0,0 +1,36 @@ +/* + * This file is part of the Meeds project (https://meeds.io/). + * Copyright (C) 2020 Meeds Association + * contact@meeds.io + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser 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 + * Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.exoplatform.services.rest.ext.webdav.method; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import javax.ws.rs.HttpMethod; + +/** + * Created by The eXo Platform SAS. + * @author Dmytro Katayev + * 22 Oct 2008 + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@HttpMethod("MOVE") +public @interface MOVE { + +} diff --git a/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/webdav/method/OPTIONS.java b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/webdav/method/OPTIONS.java new file mode 100644 index 0000000000..6436f96972 --- /dev/null +++ b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/webdav/method/OPTIONS.java @@ -0,0 +1,36 @@ +/* + * This file is part of the Meeds project (https://meeds.io/). + * Copyright (C) 2020 Meeds Association + * contact@meeds.io + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser 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 + * Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.exoplatform.services.rest.ext.webdav.method; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import javax.ws.rs.HttpMethod; + +/** + * Created by The eXo Platform SAS. + * @author Dmytro Katayev + * 22 Oct 2008 + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@HttpMethod("OPTIONS") +public @interface OPTIONS { + +} diff --git a/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/webdav/method/ORDERPATCH.java b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/webdav/method/ORDERPATCH.java new file mode 100644 index 0000000000..1731d974c6 --- /dev/null +++ b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/webdav/method/ORDERPATCH.java @@ -0,0 +1,36 @@ +/* + * This file is part of the Meeds project (https://meeds.io/). + * Copyright (C) 2020 Meeds Association + * contact@meeds.io + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser 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 + * Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.exoplatform.services.rest.ext.webdav.method; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import javax.ws.rs.HttpMethod; + +/** + * Created by The eXo Platform SAS. + * @author Dmytro Katayev + * 22 Oct 2008 + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@HttpMethod("ORDERPATCH") +public @interface ORDERPATCH { + +} diff --git a/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/webdav/method/PROPFIND.java b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/webdav/method/PROPFIND.java new file mode 100644 index 0000000000..7badde6e00 --- /dev/null +++ b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/webdav/method/PROPFIND.java @@ -0,0 +1,36 @@ +/* + * This file is part of the Meeds project (https://meeds.io/). + * Copyright (C) 2020 Meeds Association + * contact@meeds.io + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser 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 + * Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.exoplatform.services.rest.ext.webdav.method; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import javax.ws.rs.HttpMethod; + +/** + * Created by The eXo Platform SAS. + * @author Dmytro Katayev + * 22 Oct 2008 + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@HttpMethod("PROPFIND") +public @interface PROPFIND { + +} diff --git a/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/webdav/method/PROPPATCH.java b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/webdav/method/PROPPATCH.java new file mode 100644 index 0000000000..622098fa15 --- /dev/null +++ b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/webdav/method/PROPPATCH.java @@ -0,0 +1,36 @@ +/* + * This file is part of the Meeds project (https://meeds.io/). + * Copyright (C) 2020 Meeds Association + * contact@meeds.io + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser 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 + * Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.exoplatform.services.rest.ext.webdav.method; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import javax.ws.rs.HttpMethod; + +/** + * Created by The eXo Platform SAS. + * @author Dmytro Katayev + * 22 Oct 2008 + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@HttpMethod("PROPPATCH") +public @interface PROPPATCH { + +} diff --git a/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/webdav/method/REPORT.java b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/webdav/method/REPORT.java new file mode 100644 index 0000000000..3a0309d13e --- /dev/null +++ b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/webdav/method/REPORT.java @@ -0,0 +1,36 @@ +/* + * This file is part of the Meeds project (https://meeds.io/). + * Copyright (C) 2020 Meeds Association + * contact@meeds.io + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser 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 + * Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.exoplatform.services.rest.ext.webdav.method; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import javax.ws.rs.HttpMethod; + +/** + * Created by The eXo Platform SAS. + * @author Dmytro Katayev + * 22 Oct 2008 + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@HttpMethod("REPORT") +public @interface REPORT { + +} diff --git a/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/webdav/method/SEARCH.java b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/webdav/method/SEARCH.java new file mode 100644 index 0000000000..ed4c97f5b3 --- /dev/null +++ b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/webdav/method/SEARCH.java @@ -0,0 +1,36 @@ +/* + * This file is part of the Meeds project (https://meeds.io/). + * Copyright (C) 2020 Meeds Association + * contact@meeds.io + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser 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 + * Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.exoplatform.services.rest.ext.webdav.method; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import javax.ws.rs.HttpMethod; + +/** + * Created by The eXo Platform SAS. + * @author Dmytro Katayev + * 22 Oct 2008 + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@HttpMethod("SEARCH") +public @interface SEARCH { + +} diff --git a/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/webdav/method/UNCHECKOUT.java b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/webdav/method/UNCHECKOUT.java new file mode 100644 index 0000000000..a71f706f5f --- /dev/null +++ b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/webdav/method/UNCHECKOUT.java @@ -0,0 +1,36 @@ +/* + * This file is part of the Meeds project (https://meeds.io/). + * Copyright (C) 2020 Meeds Association + * contact@meeds.io + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser 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 + * Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.exoplatform.services.rest.ext.webdav.method; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import javax.ws.rs.HttpMethod; + +/** + * Created by The eXo Platform SAS. + * @author Dmytro Katayev + * 22 Oct 2008 + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@HttpMethod("UNCHECKOUT") +public @interface UNCHECKOUT { + +} diff --git a/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/webdav/method/UNLOCK.java b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/webdav/method/UNLOCK.java new file mode 100644 index 0000000000..ed37f3a5b9 --- /dev/null +++ b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/webdav/method/UNLOCK.java @@ -0,0 +1,36 @@ +/* + * This file is part of the Meeds project (https://meeds.io/). + * Copyright (C) 2020 Meeds Association + * contact@meeds.io + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser 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 + * Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.exoplatform.services.rest.ext.webdav.method; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import javax.ws.rs.HttpMethod; + +/** + * Created by The eXo Platform SAS. + * @author Dmytro Katayev + * 22 Oct 2008 + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@HttpMethod("UNLOCK") +public @interface UNLOCK { + +} diff --git a/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/webdav/method/VERSIONCONTROL.java b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/webdav/method/VERSIONCONTROL.java new file mode 100644 index 0000000000..5dc74a8d07 --- /dev/null +++ b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/rest/ext/webdav/method/VERSIONCONTROL.java @@ -0,0 +1,36 @@ +/* + * This file is part of the Meeds project (https://meeds.io/). + * Copyright (C) 2020 Meeds Association + * contact@meeds.io + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser 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 + * Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.exoplatform.services.rest.ext.webdav.method; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import javax.ws.rs.HttpMethod; + +/** + * Created by The eXo Platform SAS. + * @author Dmytro Katayev + * 22 Oct 2008 + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@HttpMethod("VERSION-CONTROL") +public @interface VERSIONCONTROL { + +} diff --git a/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/resolving/XMLResolvingService.java b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/resolving/XMLResolvingService.java new file mode 100644 index 0000000000..808101ee2d --- /dev/null +++ b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/resolving/XMLResolvingService.java @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2009 eXo Platform SAS. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.exoplatform.services.xml.resolving; + +import org.xml.sax.EntityResolver; + +/** + * Created by The eXo Platform SAS . XML resolving service - an abstract + * EntityResolver creator. + * + * @author Gennady Azarenkov + * @version $Id: XMLResolvingService.java 5799 2006-05-28 17:55:42Z geaz $ + */ + +public interface XMLResolvingService +{ + /** + * Returns a pre-created EntityResolver + * + * @return EntityResolver object + */ + EntityResolver getEntityResolver(); + +} diff --git a/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/resolving/impl/AddXMLResolvingContextPlugin.java b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/resolving/impl/AddXMLResolvingContextPlugin.java new file mode 100644 index 0000000000..cfb687544d --- /dev/null +++ b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/resolving/impl/AddXMLResolvingContextPlugin.java @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2009 eXo Platform SAS. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.exoplatform.services.xml.resolving.impl; + +import org.exoplatform.container.component.BaseComponentPlugin; +import org.exoplatform.container.xml.InitParams; +import org.exoplatform.container.xml.PropertiesParam; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +/** + * @author Andrey Parfonov + * @version $Id: $ + */ +public class AddXMLResolvingContextPlugin extends BaseComponentPlugin +{ + + private Map publicIDs_ = new HashMap(); + + private Map systemIDs_ = new HashMap(); + + public AddXMLResolvingContextPlugin(InitParams params) + { + if (params != null) + { + Iterator iterator = params.getPropertiesParamIterator(); + while (iterator.hasNext()) + { + PropertiesParam propertiesParam = iterator.next(); + String uri = propertiesParam.getProperty("uri"); + String publicId = propertiesParam.getProperty("publicId"); + String systemId = propertiesParam.getProperty("systemId"); + if (publicId != null && uri != null) + publicIDs_.put(publicId, uri); + if (systemId != null && uri != null) + systemIDs_.put(systemId, uri); + } + } + } + + public Map getPublicIDsResolvingtable() + { + return publicIDs_; + } + + public Map getSystemIDsResolvingtable() + { + return systemIDs_; + } + +} diff --git a/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/resolving/impl/XMLResolver.java b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/resolving/impl/XMLResolver.java new file mode 100644 index 0000000000..d484d1e731 --- /dev/null +++ b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/resolving/impl/XMLResolver.java @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2009 eXo Platform SAS. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.exoplatform.services.xml.resolving.impl; + +import org.xml.sax.EntityResolver; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +import java.io.IOException; +import java.util.Map; + +/** + * @author Andrey Parfonov + * @version $Id: $ + */ +public class XMLResolver implements EntityResolver +{ + + private Map publicIDs_; + + private Map systemIDs_; + + /** + * Is publicID prefer. + */ + private boolean publicIDPrefer_ = false; + + public XMLResolver(Map publicIDs, Map systemIDs) + { + publicIDs_ = publicIDs; + systemIDs_ = systemIDs; + } + + /* + * (non-Javadoc) + * @see org.xml.sax.EntityResolver#resolveEntity(java.lang.String, + * java.lang.String) + */ + public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException + { + String entity = null; + // if publicId is prefer first check publicIDs table + if (publicIDPrefer_ && publicId != null && publicId.length() != 0) + entity = publicIDs_.get(publicId); + // if publicId is not prefer + if (entity == null && systemId != null && systemId.length() != 0) + entity = systemIDs_.get(systemId); + // if entity still null try get it from publicIDs table + if (entity == null && publicId != null && publicId.length() != 0) + entity = publicIDs_.get(publicId); + if (entity != null) + { + if (this.getClass().getResource(entity) != null) + { + InputSource src = new InputSource(Thread.currentThread().getContextClassLoader().getResourceAsStream(entity)); + src.setSystemId(Thread.currentThread().getContextClassLoader().getResource(entity).getPath()); + return src; + } + } + return null; + } + + public boolean isPublicIDPrefer() + { + return publicIDPrefer_; + } + + public void setPublicIDPrefer(boolean publicPrefer) + { + publicIDPrefer_ = publicPrefer; + } + +} diff --git a/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/resolving/impl/XMLResolvingServiceImpl.java b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/resolving/impl/XMLResolvingServiceImpl.java new file mode 100644 index 0000000000..7a45bde3fe --- /dev/null +++ b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/resolving/impl/XMLResolvingServiceImpl.java @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2009 eXo Platform SAS. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.exoplatform.services.xml.resolving.impl; + +import org.exoplatform.container.component.ComponentPlugin; +import org.exoplatform.services.log.ExoLogger; +import org.exoplatform.services.log.Log; +import org.exoplatform.services.xml.resolving.XMLResolvingService; +import org.xml.sax.EntityResolver; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +/** + * @author Andrey Parfonov + * @version $Id: $ + */ +public class XMLResolvingServiceImpl implements XMLResolvingService +{ + + private static final Log LOG = ExoLogger.getLogger("exo.core.component.xml-processing.XMLResolvingServiceImpl"); + + private Map publicIDs_ = new HashMap(); + + private Map systemIDs_ = new HashMap(); + + public XMLResolvingServiceImpl() + { + } + + public EntityResolver getEntityResolver() + { + return new XMLResolver(publicIDs_, systemIDs_); + } + + private void addEntityPublicID(String publicId, String uri) + { + if (publicIDs_.get(publicId) != null) + throw new IllegalArgumentException("Entity whith publicId " + publicId + " already exists."); + publicIDs_.put(publicId, uri); + LOG.info("New entries to ResolvingService added (public) : " + publicId + " : " + uri); + } + + private void addEntitySystemID(String systemId, String uri) + { + if (systemIDs_.get(systemId) != null) + throw new IllegalArgumentException("Entity whith systemId " + systemId + " already exists."); + systemIDs_.put(systemId, uri); + LOG.info("New entries to ResolvingService added (system) : " + systemId + " : " + uri); + } + + public void addPlugin(ComponentPlugin plugin) + { + if (plugin instanceof AddXMLResolvingContextPlugin) + { + AddXMLResolvingContextPlugin resolvingContextPlugin = (AddXMLResolvingContextPlugin)plugin; + Map t = resolvingContextPlugin.getPublicIDsResolvingtable(); + Set keys = t.keySet(); + for (String key : keys) + { + addEntityPublicID(key, t.get(key)); + } + t = resolvingContextPlugin.getSystemIDsResolvingtable(); + keys = t.keySet(); + for (String key : keys) + { + addEntitySystemID(key, t.get(key)); + } + } + } + +} diff --git a/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/transform/AbstractTransformer.java b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/transform/AbstractTransformer.java new file mode 100644 index 0000000000..5dca7eadd8 --- /dev/null +++ b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/transform/AbstractTransformer.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2009 eXo Platform SAS. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.exoplatform.services.xml.transform; + +import javax.xml.transform.Result; +import javax.xml.transform.Source; +import javax.xml.transform.TransformerException; + +/** + * Created by The eXo Platform SAS . + * + * @author Gennady Azarenkov + * @author Alexander Kravchuk + * @version $Id: AbstractTransformer.java 5799 2006-05-28 17:55:42Z geaz $ + */ + +public interface AbstractTransformer +{ + /** + * Initialize a result of transformation + * + * @param result Result + * @throws NotSupportedIOTypeException if try to initialize with not supported + * implementation of Result + */ + void initResult(Result result) throws NotSupportedIOTypeException; + + /** + * Transform source data to result + * + * @param source Source - input of transformation + * @throws NotSupportedIOTypeException if not supported implementation of + * Source + * @throws TransformerException if error occurred on transformation process + * @throws IllegalStateException if result not initialized by initResult + */ + void transform(Source source) throws NotSupportedIOTypeException, TransformerException, IllegalStateException; +} diff --git a/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/transform/EncodingMap.java b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/transform/EncodingMap.java new file mode 100644 index 0000000000..301948ddcc --- /dev/null +++ b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/transform/EncodingMap.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2009 eXo Platform SAS. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.exoplatform.services.xml.transform; + +import org.exoplatform.container.spi.DefinitionByType; +import org.exoplatform.services.xml.transform.impl.EncodingMapImpl; + +/** + * Created by The eXo Platform SAS . Conversions between IANA encoding names and + * Java encoding names, + * + * @author Alexander Kravchuk + * @version $Id: + */ +@DefinitionByType(type = EncodingMapImpl.class) +public interface EncodingMap +{ + public String convertIANA2Java(String iana); + + public String convertJava2IANA(String java); +} diff --git a/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/transform/NotSupportedIOTypeException.java b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/transform/NotSupportedIOTypeException.java new file mode 100644 index 0000000000..e29711f49c --- /dev/null +++ b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/transform/NotSupportedIOTypeException.java @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2009 eXo Platform SAS. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.exoplatform.services.xml.transform; + +import javax.xml.transform.Result; +import javax.xml.transform.Source; + +/** + * Created by The eXo Platform SAS . + * + * @author Gennady Azarenkov + * @version $Id: NotSupportedIOTypeException.java 5799 2006-05-28 17:55:42Z geaz + * $ + */ + +public class NotSupportedIOTypeException extends Exception +{ + + /** Constructs an Exception without a message. */ + public NotSupportedIOTypeException() + { + super(); + } + + /** Constructs an Exception with a message. */ + public NotSupportedIOTypeException(Result result) + { + super("Result type " + result.getClass().getName() + " is not supported by this transformer."); + } + + /** Constructs an Exception with a message. */ + public NotSupportedIOTypeException(Source source) + { + super("Source type " + source.getClass().getName() + " is not supported by this transformer."); + } + + /** + * Constructs an Exception with a detailed message. + * + * @param message The message associated with the exception. + */ + public NotSupportedIOTypeException(String message) + { + super(message); + } +} diff --git a/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/transform/PipeTransformer.java b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/transform/PipeTransformer.java new file mode 100644 index 0000000000..ff494b8c3b --- /dev/null +++ b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/transform/PipeTransformer.java @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2009 eXo Platform SAS. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.exoplatform.services.xml.transform; + +import javax.xml.transform.Result; + +/** + * Created by The eXo Platform SAS . + * + * @author Alexander Kravchuk + * @version $Id: PipeTransformer.java 5799 2006-05-28 17:55:42Z geaz $ + */ + +public interface PipeTransformer extends AbstractTransformer +{ + Result getTransformerAsResult(); +} diff --git a/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/transform/impl/EncodingMapImpl.java b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/transform/impl/EncodingMapImpl.java new file mode 100644 index 0000000000..4fc22cdb9e --- /dev/null +++ b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/transform/impl/EncodingMapImpl.java @@ -0,0 +1,448 @@ +/* + * Copyright (C) 2009 eXo Platform SAS. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.exoplatform.services.xml.transform.impl; + +import org.exoplatform.services.log.ExoLogger; +import org.exoplatform.services.log.Log; +import org.exoplatform.services.xml.transform.EncodingMap; + +import java.util.Hashtable; + +/** + * Created by The eXo Platform SAS . Conversions between IANA encoding names and + * Java encoding names, + * See http://java.sun.com/j2se/1.5.0/docs/guide/intl/encoding.doc.html + * + * @author Alexander Kravchuk + * @version $Id: + */ + +public class EncodingMapImpl implements EncodingMap +{ + private static final Log LOG = ExoLogger.getLogger("exo.core.component.xml-processing.EncodingMapImpl"); + + protected final static Hashtable IANA2JavaMap = new Hashtable(); + + protected final static Hashtable Java2IANAMap = new Hashtable(); + + public static void addIANA2JavaMapping(String iana, String java) + { + IANA2JavaMap.put(iana, java); + if (Java2IANAMap.get(java) == null) + { + Java2IANAMap.put(java, iana); + } + } + + public static void removeIANA2JavaMapping(String iana, String java) + { + IANA2JavaMap.remove(iana); + Java2IANAMap.remove(java); + } + + public static void IANA2JavaMapping(String iana, String java) + { + IANA2JavaMap.put(iana, java); + Java2IANAMap.put(java, iana); + } + + public String convertIANA2Java(String iana) + { + return IANA2JavaMap.get(iana); + } + + public String convertJava2IANA(String java) + { + LOG.debug("convert [" + java + "] to iana coding [" + Java2IANAMap.get(java) + "]"); + return Java2IANAMap.get(java); + } + + static + { + addIANA2JavaMapping("BIG5", "Big5"); + addIANA2JavaMapping("CSBIG5", "Big5"); + addIANA2JavaMapping("CP037", "CP037"); + addIANA2JavaMapping("IBM037", "CP037"); + addIANA2JavaMapping("CSIBM037", "CP037"); + addIANA2JavaMapping("EBCDIC-CP-US", "CP037"); + addIANA2JavaMapping("EBCDIC-CP-CA", "CP037"); + addIANA2JavaMapping("EBCDIC-CP-NL", "CP037"); + addIANA2JavaMapping("EBCDIC-CP-WT", "CP037"); + addIANA2JavaMapping("IBM273", "CP273"); + addIANA2JavaMapping("CP273", "CP273"); + addIANA2JavaMapping("CSIBM273", "CP273"); + addIANA2JavaMapping("IBM277", "CP277"); + addIANA2JavaMapping("CP277", "CP277"); + addIANA2JavaMapping("CSIBM277", "CP277"); + addIANA2JavaMapping("EBCDIC-CP-DK", "CP277"); + addIANA2JavaMapping("EBCDIC-CP-NO", "CP277"); + addIANA2JavaMapping("IBM278", "CP278"); + addIANA2JavaMapping("CP278", "CP278"); + addIANA2JavaMapping("CSIBM278", "CP278"); + addIANA2JavaMapping("EBCDIC-CP-FI", "CP278"); + addIANA2JavaMapping("EBCDIC-CP-SE", "CP278"); + addIANA2JavaMapping("IBM280", "CP280"); + addIANA2JavaMapping("CP280", "CP280"); + addIANA2JavaMapping("CSIBM280", "CP280"); + addIANA2JavaMapping("EBCDIC-CP-IT", "CP280"); + addIANA2JavaMapping("IBM284", "CP284"); + addIANA2JavaMapping("CP284", "CP284"); + addIANA2JavaMapping("CSIBM284", "CP284"); + addIANA2JavaMapping("EBCDIC-CP-ES", "CP284"); + addIANA2JavaMapping("EBCDIC-CP-GB", "CP285"); + addIANA2JavaMapping("IBM285", "CP285"); + addIANA2JavaMapping("CP285", "CP285"); + addIANA2JavaMapping("CSIBM285", "CP285"); + addIANA2JavaMapping("EBCDIC-JP-KANA", "CP290"); + addIANA2JavaMapping("IBM290", "CP290"); + addIANA2JavaMapping("CP290", "CP290"); + addIANA2JavaMapping("CSIBM290", "CP290"); + addIANA2JavaMapping("EBCDIC-CP-FR", "CP297"); + addIANA2JavaMapping("IBM297", "CP297"); + addIANA2JavaMapping("CP297", "CP297"); + addIANA2JavaMapping("CSIBM297", "CP297"); + addIANA2JavaMapping("EBCDIC-CP-AR1", "CP420"); + addIANA2JavaMapping("IBM420", "CP420"); + addIANA2JavaMapping("CP420", "CP420"); + addIANA2JavaMapping("CSIBM420", "CP420"); + addIANA2JavaMapping("EBCDIC-CP-HE", "CP424"); + addIANA2JavaMapping("IBM424", "CP424"); + addIANA2JavaMapping("CP424", "CP424"); + addIANA2JavaMapping("CSIBM424", "CP424"); + addIANA2JavaMapping("IBM437", "CP437"); + addIANA2JavaMapping("437", "CP437"); + addIANA2JavaMapping("CP437", "CP437"); + addIANA2JavaMapping("CSPC8CODEPAGE437", "CP437"); + addIANA2JavaMapping("EBCDIC-CP-CH", "CP500"); + addIANA2JavaMapping("IBM500", "CP500"); + addIANA2JavaMapping("CP500", "CP500"); + addIANA2JavaMapping("CSIBM500", "CP500"); + addIANA2JavaMapping("EBCDIC-CP-CH", "CP500"); + addIANA2JavaMapping("EBCDIC-CP-BE", "CP500"); + addIANA2JavaMapping("IBM775", "CP775"); + addIANA2JavaMapping("CP775", "CP775"); + addIANA2JavaMapping("CSPC775BALTIC", "CP775"); + addIANA2JavaMapping("IBM850", "CP850"); + addIANA2JavaMapping("850", "CP850"); + addIANA2JavaMapping("CP850", "CP850"); + addIANA2JavaMapping("CSPC850MULTILINGUAL", "CP850"); + addIANA2JavaMapping("IBM852", "CP852"); + addIANA2JavaMapping("852", "CP852"); + addIANA2JavaMapping("CP852", "CP852"); + addIANA2JavaMapping("CSPCP852", "CP852"); + addIANA2JavaMapping("IBM855", "CP855"); + addIANA2JavaMapping("855", "CP855"); + addIANA2JavaMapping("CP855", "CP855"); + addIANA2JavaMapping("CSIBM855", "CP855"); + addIANA2JavaMapping("IBM857", "CP857"); + addIANA2JavaMapping("857", "CP857"); + addIANA2JavaMapping("CP857", "CP857"); + addIANA2JavaMapping("CSIBM857", "CP857"); + addIANA2JavaMapping("IBM00858", "CP858"); + addIANA2JavaMapping("CP00858", "CP858"); + addIANA2JavaMapping("CCSID00858", "CP858"); + addIANA2JavaMapping("IBM860", "CP860"); + addIANA2JavaMapping("860", "CP860"); + addIANA2JavaMapping("CP860", "CP860"); + addIANA2JavaMapping("CSIBM860", "CP860"); + addIANA2JavaMapping("IBM861", "CP861"); + addIANA2JavaMapping("861", "CP861"); + addIANA2JavaMapping("CP861", "CP861"); + addIANA2JavaMapping("CP-IS", "CP861"); + addIANA2JavaMapping("CSIBM861", "CP861"); + addIANA2JavaMapping("IBM862", "CP862"); + addIANA2JavaMapping("862", "CP862"); + addIANA2JavaMapping("CP862", "CP862"); + addIANA2JavaMapping("CSPC862LATINHEBREW", "CP862"); + addIANA2JavaMapping("IBM863", "CP863"); + addIANA2JavaMapping("863", "CP863"); + addIANA2JavaMapping("CP863", "CP863"); + addIANA2JavaMapping("CSIBM863", "CP863"); + addIANA2JavaMapping("IBM864", "CP864"); + addIANA2JavaMapping("CP864", "CP864"); + addIANA2JavaMapping("CSIBM864", "CP864"); + addIANA2JavaMapping("IBM865", "CP865"); + addIANA2JavaMapping("865", "CP865"); + addIANA2JavaMapping("CP865", "CP865"); + addIANA2JavaMapping("CSIBM865", "CP865"); + addIANA2JavaMapping("IBM866", "CP866"); + addIANA2JavaMapping("866", "CP866"); + addIANA2JavaMapping("CP866", "CP866"); + addIANA2JavaMapping("CSIBM866", "CP866"); + addIANA2JavaMapping("IBM868", "CP868"); + addIANA2JavaMapping("CP868", "CP868"); + addIANA2JavaMapping("CSIBM868", "CP868"); + addIANA2JavaMapping("CP-AR", "CP868"); + addIANA2JavaMapping("IBM869", "CP869"); + addIANA2JavaMapping("CP869", "CP869"); + addIANA2JavaMapping("CSIBM869", "CP869"); + addIANA2JavaMapping("CP-GR", "CP869"); + addIANA2JavaMapping("IBM870", "CP870"); + addIANA2JavaMapping("CP870", "CP870"); + addIANA2JavaMapping("CSIBM870", "CP870"); + addIANA2JavaMapping("EBCDIC-CP-ROECE", "CP870"); + addIANA2JavaMapping("EBCDIC-CP-YU", "CP870"); + addIANA2JavaMapping("IBM871", "CP871"); + addIANA2JavaMapping("CP871", "CP871"); + addIANA2JavaMapping("CSIBM871", "CP871"); + addIANA2JavaMapping("EBCDIC-CP-IS", "CP871"); + addIANA2JavaMapping("IBM918", "CP918"); + addIANA2JavaMapping("CP918", "CP918"); + addIANA2JavaMapping("CSIBM918", "CP918"); + addIANA2JavaMapping("EBCDIC-CP-AR2", "CP918"); + addIANA2JavaMapping("IBM00924", "CP924"); + addIANA2JavaMapping("CP00924", "CP924"); + addIANA2JavaMapping("CCSID00924", "CP924"); + // is this an error??? + addIANA2JavaMapping("EBCDIC-LATIN9--EURO", "CP924"); + addIANA2JavaMapping("IBM1026", "CP1026"); + addIANA2JavaMapping("CP1026", "CP1026"); + addIANA2JavaMapping("CSIBM1026", "CP1026"); + addIANA2JavaMapping("IBM01140", "Cp1140"); + addIANA2JavaMapping("CP01140", "Cp1140"); + addIANA2JavaMapping("CCSID01140", "Cp1140"); + addIANA2JavaMapping("IBM01141", "Cp1141"); + addIANA2JavaMapping("CP01141", "Cp1141"); + addIANA2JavaMapping("CCSID01141", "Cp1141"); + addIANA2JavaMapping("IBM01142", "Cp1142"); + addIANA2JavaMapping("CP01142", "Cp1142"); + addIANA2JavaMapping("CCSID01142", "Cp1142"); + addIANA2JavaMapping("IBM01143", "Cp1143"); + addIANA2JavaMapping("CP01143", "Cp1143"); + addIANA2JavaMapping("CCSID01143", "Cp1143"); + addIANA2JavaMapping("IBM01144", "Cp1144"); + addIANA2JavaMapping("CP01144", "Cp1144"); + addIANA2JavaMapping("CCSID01144", "Cp1144"); + addIANA2JavaMapping("IBM01145", "Cp1145"); + addIANA2JavaMapping("CP01145", "Cp1145"); + addIANA2JavaMapping("CCSID01145", "Cp1145"); + addIANA2JavaMapping("IBM01146", "Cp1146"); + addIANA2JavaMapping("CP01146", "Cp1146"); + addIANA2JavaMapping("CCSID01146", "Cp1146"); + addIANA2JavaMapping("IBM01147", "Cp1147"); + addIANA2JavaMapping("CP01147", "Cp1147"); + addIANA2JavaMapping("CCSID01147", "Cp1147"); + addIANA2JavaMapping("IBM01148", "Cp1148"); + addIANA2JavaMapping("CP01148", "Cp1148"); + addIANA2JavaMapping("CCSID01148", "Cp1148"); + addIANA2JavaMapping("IBM01149", "Cp1149"); + addIANA2JavaMapping("CP01149", "Cp1149"); + addIANA2JavaMapping("CCSID01149", "Cp1149"); + addIANA2JavaMapping("EUC-JP", "EUCJIS"); + addIANA2JavaMapping("CSEUCPKDFMTJAPANESE", "EUCJIS"); + addIANA2JavaMapping("EXTENDED_UNIX_CODE_PACKED_FORMAT_FOR_JAPANESE", "EUCJIS"); + addIANA2JavaMapping("EUC-KR", "KSC5601"); + addIANA2JavaMapping("CSEUCKR", "KSC5601"); + addIANA2JavaMapping("KS_C_5601-1987", "KS_C_5601-1987"); + addIANA2JavaMapping("ISO-IR-149", "KS_C_5601-1987"); + addIANA2JavaMapping("KS_C_5601-1989", "KS_C_5601-1987"); + addIANA2JavaMapping("KSC_5601", "KS_C_5601-1987"); + addIANA2JavaMapping("KOREAN", "KS_C_5601-1987"); + addIANA2JavaMapping("CSKSC56011987", "KS_C_5601-1987"); + addIANA2JavaMapping("GB2312", "GB2312"); + addIANA2JavaMapping("CSGB2312", "GB2312"); + addIANA2JavaMapping("ISO-2022-JP", "JIS"); + addIANA2JavaMapping("CSISO2022JP", "JIS"); + addIANA2JavaMapping("ISO-2022-KR", "ISO2022KR"); + addIANA2JavaMapping("CSISO2022KR", "ISO2022KR"); + addIANA2JavaMapping("ISO-2022-CN", "ISO2022CN"); + + addIANA2JavaMapping("X0201", "JIS0201"); + addIANA2JavaMapping("CSISO13JISC6220JP", "JIS0201"); + addIANA2JavaMapping("X0208", "JIS0208"); + addIANA2JavaMapping("ISO-IR-87", "JIS0208"); + addIANA2JavaMapping("X0208dbiJIS_X0208-1983", "JIS0208"); + addIANA2JavaMapping("CSISO87JISX0208", "JIS0208"); + addIANA2JavaMapping("X0212", "JIS0212"); + addIANA2JavaMapping("ISO-IR-159", "JIS0212"); + addIANA2JavaMapping("CSISO159JISX02121990", "JIS0212"); + addIANA2JavaMapping("GB18030", "GB18030"); + addIANA2JavaMapping("GBK", "GBK"); + addIANA2JavaMapping("CP936", "GBK"); + addIANA2JavaMapping("MS936", "GBK"); + addIANA2JavaMapping("WINDOWS-936", "GBK"); + addIANA2JavaMapping("SHIFT_JIS", "SJIS"); + addIANA2JavaMapping("CSSHIFTJIS", "SJIS"); + addIANA2JavaMapping("MS_KANJI", "SJIS"); + addIANA2JavaMapping("WINDOWS-31J", "MS932"); + addIANA2JavaMapping("CSWINDOWS31J", "MS932"); + + // Add support for Cp1252 and its friends + addIANA2JavaMapping("WINDOWS-1250", "Cp1250"); + addIANA2JavaMapping("WINDOWS-1251", "Cp1251"); + addIANA2JavaMapping("WINDOWS-1252", "Cp1252"); + addIANA2JavaMapping("WINDOWS-1253", "Cp1253"); + addIANA2JavaMapping("WINDOWS-1254", "Cp1254"); + addIANA2JavaMapping("WINDOWS-1255", "Cp1255"); + addIANA2JavaMapping("WINDOWS-1256", "Cp1256"); + addIANA2JavaMapping("WINDOWS-1257", "Cp1257"); + addIANA2JavaMapping("WINDOWS-1258", "Cp1258"); + addIANA2JavaMapping("TIS-620", "TIS620"); + + addIANA2JavaMapping("ISO-8859-1", "ISO8859_1"); + addIANA2JavaMapping("ISO-IR-100", "ISO8859_1"); + addIANA2JavaMapping("ISO_8859-1", "ISO8859_1"); + addIANA2JavaMapping("LATIN1", "ISO8859_1"); + addIANA2JavaMapping("CSISOLATIN1", "ISO8859_1"); + addIANA2JavaMapping("L1", "ISO8859_1"); + addIANA2JavaMapping("IBM819", "ISO8859_1"); + addIANA2JavaMapping("CP819", "ISO8859_1"); + + addIANA2JavaMapping("ISO-8859-2", "ISO8859_2"); + addIANA2JavaMapping("ISO-IR-101", "ISO8859_2"); + addIANA2JavaMapping("ISO_8859-2", "ISO8859_2"); + addIANA2JavaMapping("LATIN2", "ISO8859_2"); + addIANA2JavaMapping("CSISOLATIN2", "ISO8859_2"); + addIANA2JavaMapping("L2", "ISO8859_2"); + + addIANA2JavaMapping("ISO-8859-3", "ISO8859_3"); + addIANA2JavaMapping("ISO-IR-109", "ISO8859_3"); + addIANA2JavaMapping("ISO_8859-3", "ISO8859_3"); + addIANA2JavaMapping("LATIN3", "ISO8859_3"); + addIANA2JavaMapping("CSISOLATIN3", "ISO8859_3"); + addIANA2JavaMapping("L3", "ISO8859_3"); + + addIANA2JavaMapping("ISO-8859-4", "ISO8859_4"); + addIANA2JavaMapping("ISO-IR-110", "ISO8859_4"); + addIANA2JavaMapping("ISO_8859-4", "ISO8859_4"); + addIANA2JavaMapping("LATIN4", "ISO8859_4"); + addIANA2JavaMapping("CSISOLATIN4", "ISO8859_4"); + addIANA2JavaMapping("L4", "ISO8859_4"); + + addIANA2JavaMapping("ISO-8859-5", "ISO8859_5"); + addIANA2JavaMapping("ISO-IR-144", "ISO8859_5"); + addIANA2JavaMapping("ISO_8859-5", "ISO8859_5"); + addIANA2JavaMapping("CYRILLIC", "ISO8859_5"); + addIANA2JavaMapping("CSISOLATINCYRILLIC", "ISO8859_5"); + + addIANA2JavaMapping("ISO-8859-6", "ISO8859_6"); + addIANA2JavaMapping("ISO-IR-127", "ISO8859_6"); + addIANA2JavaMapping("ISO_8859-6", "ISO8859_6"); + addIANA2JavaMapping("ECMA-114", "ISO8859_6"); + addIANA2JavaMapping("ASMO-708", "ISO8859_6"); + addIANA2JavaMapping("ARABIC", "ISO8859_6"); + addIANA2JavaMapping("CSISOLATINARABIC", "ISO8859_6"); + + addIANA2JavaMapping("ISO-8859-7", "ISO8859_7"); + addIANA2JavaMapping("ISO-IR-126", "ISO8859_7"); + addIANA2JavaMapping("ISO_8859-7", "ISO8859_7"); + addIANA2JavaMapping("ELOT_928", "ISO8859_7"); + addIANA2JavaMapping("ECMA-118", "ISO8859_7"); + addIANA2JavaMapping("GREEK", "ISO8859_7"); + addIANA2JavaMapping("CSISOLATINGREEK", "ISO8859_7"); + addIANA2JavaMapping("GREEK8", "ISO8859_7"); + + addIANA2JavaMapping("ISO-8859-8", "ISO8859_8"); + addIANA2JavaMapping("ISO-8859-8-I", "ISO8859_8"); // added since this + // encoding only differs + // w.r.t. presentation + addIANA2JavaMapping("ISO-IR-138", "ISO8859_8"); + addIANA2JavaMapping("ISO_8859-8", "ISO8859_8"); + addIANA2JavaMapping("HEBREW", "ISO8859_8"); + addIANA2JavaMapping("CSISOLATINHEBREW", "ISO8859_8"); + + addIANA2JavaMapping("ISO-8859-9", "ISO8859_9"); + addIANA2JavaMapping("ISO-IR-148", "ISO8859_9"); + addIANA2JavaMapping("ISO_8859-9", "ISO8859_9"); + addIANA2JavaMapping("LATIN5", "ISO8859_9"); + addIANA2JavaMapping("CSISOLATIN5", "ISO8859_9"); + addIANA2JavaMapping("L5", "ISO8859_9"); + + addIANA2JavaMapping("ISO-8859-13", "ISO8859_13"); + + addIANA2JavaMapping("ISO-8859-15", "ISO8859_15_FDIS"); + addIANA2JavaMapping("ISO_8859-15", "ISO8859_15_FDIS"); + addIANA2JavaMapping("LATIN-9", "ISO8859_15_FDIS"); + + addIANA2JavaMapping("KOI8-R", "KOI8_R"); + addIANA2JavaMapping("CSKOI8R", "KOI8_R"); + addIANA2JavaMapping("US-ASCII", "ASCII"); + addIANA2JavaMapping("ISO-IR-6", "ASCII"); + addIANA2JavaMapping("ANSI_X3.4-1968", "ASCII"); + addIANA2JavaMapping("ANSI_X3.4-1986", "ASCII"); + addIANA2JavaMapping("ISO_646.IRV:1991", "ASCII"); + addIANA2JavaMapping("ASCII", "ASCII"); + addIANA2JavaMapping("CSASCII", "ASCII"); + addIANA2JavaMapping("ISO646-US", "ASCII"); + addIANA2JavaMapping("US", "ASCII"); + addIANA2JavaMapping("IBM367", "ASCII"); + addIANA2JavaMapping("CP367", "ASCII"); + addIANA2JavaMapping("UTF-8", "UTF-8"); + addIANA2JavaMapping("UTF-16", "UTF-16"); + addIANA2JavaMapping("UTF-16BE", "UnicodeBig"); + addIANA2JavaMapping("UTF-16LE", "UnicodeLittle"); + + // support for 1047, as proposed to be added to the + // IANA registry in + // http://lists.w3.org/Archives/Public/ietf-charset/2002JulSep/0049.html + addIANA2JavaMapping("IBM-1047", "Cp1047"); + addIANA2JavaMapping("IBM1047", "Cp1047"); + addIANA2JavaMapping("CP1047", "Cp1047"); + + // Adding new aliases as proposed in + // http://lists.w3.org/Archives/Public/ietf-charset/2002JulSep/0058.html + addIANA2JavaMapping("IBM-37", "CP037"); + addIANA2JavaMapping("IBM-273", "CP273"); + addIANA2JavaMapping("IBM-277", "CP277"); + addIANA2JavaMapping("IBM-278", "CP278"); + addIANA2JavaMapping("IBM-280", "CP280"); + addIANA2JavaMapping("IBM-284", "CP284"); + addIANA2JavaMapping("IBM-285", "CP285"); + addIANA2JavaMapping("IBM-290", "CP290"); + addIANA2JavaMapping("IBM-297", "CP297"); + addIANA2JavaMapping("IBM-420", "CP420"); + addIANA2JavaMapping("IBM-424", "CP424"); + addIANA2JavaMapping("IBM-437", "CP437"); + addIANA2JavaMapping("IBM-500", "CP500"); + addIANA2JavaMapping("IBM-775", "CP775"); + addIANA2JavaMapping("IBM-850", "CP850"); + addIANA2JavaMapping("IBM-852", "CP852"); + addIANA2JavaMapping("IBM-855", "CP855"); + addIANA2JavaMapping("IBM-857", "CP857"); + addIANA2JavaMapping("IBM-858", "CP858"); + addIANA2JavaMapping("IBM-860", "CP860"); + addIANA2JavaMapping("IBM-861", "CP861"); + addIANA2JavaMapping("IBM-862", "CP862"); + addIANA2JavaMapping("IBM-863", "CP863"); + addIANA2JavaMapping("IBM-864", "CP864"); + addIANA2JavaMapping("IBM-865", "CP865"); + addIANA2JavaMapping("IBM-866", "CP866"); + addIANA2JavaMapping("IBM-868", "CP868"); + addIANA2JavaMapping("IBM-869", "CP869"); + addIANA2JavaMapping("IBM-870", "CP870"); + addIANA2JavaMapping("IBM-871", "CP871"); + addIANA2JavaMapping("IBM-918", "CP918"); + addIANA2JavaMapping("IBM-924", "CP924"); + addIANA2JavaMapping("IBM-1026", "CP1026"); + addIANA2JavaMapping("IBM-1140", "Cp1140"); + addIANA2JavaMapping("IBM-1141", "Cp1141"); + addIANA2JavaMapping("IBM-1142", "Cp1142"); + addIANA2JavaMapping("IBM-1143", "Cp1143"); + addIANA2JavaMapping("IBM-1144", "Cp1144"); + addIANA2JavaMapping("IBM-1145", "Cp1145"); + addIANA2JavaMapping("IBM-1146", "Cp1146"); + addIANA2JavaMapping("IBM-1147", "Cp1147"); + addIANA2JavaMapping("IBM-1148", "Cp1148"); + addIANA2JavaMapping("IBM-1149", "Cp1149"); + addIANA2JavaMapping("IBM-819", "ISO8859_1"); + addIANA2JavaMapping("IBM-367", "ASCII"); + // https://jira.jboss.org/jira/browse/EXOJCR-588 + addIANA2JavaMapping("x-MacRoman", "MacRoman"); + } +} diff --git a/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/transform/impl/TransformerBase.java b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/transform/impl/TransformerBase.java new file mode 100644 index 0000000000..6434bf80de --- /dev/null +++ b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/transform/impl/TransformerBase.java @@ -0,0 +1,270 @@ +/* + * Copyright (C) 2009 eXo Platform SAS. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.exoplatform.services.xml.transform.impl; + +import org.exoplatform.services.log.ExoLogger; +import org.exoplatform.services.log.Log; +import org.exoplatform.services.xml.resolving.XMLResolvingService; +import org.exoplatform.services.xml.transform.AbstractTransformer; +import org.exoplatform.services.xml.transform.NotSupportedIOTypeException; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.XMLReader; +import org.xml.sax.helpers.XMLReaderFactory; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.security.PrivilegedExceptionAction; + +import javax.xml.transform.Result; +import javax.xml.transform.Source; +import javax.xml.transform.TransformerException; +import javax.xml.transform.sax.SAXResult; +import javax.xml.transform.sax.SAXSource; +import javax.xml.transform.sax.SAXTransformerFactory; +import javax.xml.transform.sax.TransformerHandler; +import javax.xml.transform.stream.StreamResult; + +/** + * Created by The eXo Platform SAS . + * + * @author Alexander Kravchuk + * @version $Id: TransformerBase.java 5799 2006-05-28 17:55:42Z geaz $ + */ +public abstract class TransformerBase implements AbstractTransformer +{ + private Result result = null; + + protected static final Log LOG = ExoLogger.getLogger("exo.core.component.xml-processing.TransformerBase"); + + protected SAXTransformerFactory tSAXFactory; + + protected XMLResolvingService resolvingService; + + public TransformerBase() + { + LOG.debug("Current javax.xml.parsers.SAXParserFactory sys property [ " + + System.getProperty("javax.xml.parsers.SAXParserFactory", "-Not set-") + "]"); + + tSAXFactory = (SAXTransformerFactory)SAXTransformerFactory.newInstance(); + } + + /** + * TODO change. Must no use explicit parser class name + */ + static public XMLReader getXMLReader() throws SAXException + { + return XMLReaderFactory.createXMLReader(); + } + + public void setResolvingService(XMLResolvingService r) + { + resolvingService = r; + } + + /** + * override when need some operation after initialization result in + * transformer + */ + protected void afterInitResult() + { + LOG.debug("Result is set"); + } + + final public void initResult(Result result) throws NotSupportedIOTypeException + { + if (!isResultSupported(result)) + { + throw new NotSupportedIOTypeException(result); + } + this.result = result; + afterInitResult(); + } + + protected Result getResult() + { + return this.result; + } + + protected boolean isSourceSupported(Source source) + { + return true; + } + + protected boolean isResultSupported(Result result) + { + return true; + } + + protected abstract void internalTransform(Source src) throws NotSupportedIOTypeException, TransformerException, + IllegalStateException; + + final public void transform(Source source) throws NotSupportedIOTypeException, TransformerException, + IllegalStateException + { + + if (!isSourceSupported(source)) + { + LOG.error("source of type " + source.getClass().getName() + " not supported"); + throw new NotSupportedIOTypeException(source); + } + + if (this.result == null) + { + LOG.error("Result not set"); + throw new IllegalStateException("Result not specified. See initResult(Result)"); + } + + internalTransform(source); + } + + /** + * Tranform InputStream to specified result, according to type of result + * + * @param input InputStream + * @param result Result + * @throws TransformerException + */ + + public void transformInputStream2Result(InputStream input, Result result) throws TransformerException + { + LOG.debug("Transform InputStream to result of type " + result.getClass().getName()); + + // StreamResult - write data from InputStream to OutputStream + if (result instanceof StreamResult) + { + OutputStream outputStream = ((StreamResult)result).getOutputStream(); + try + { + int counter = 0; + while (input.available() > 0) + { + byte[] byteArray = new byte[input.available()]; + int readBytes = input.read(byteArray); + counter += readBytes; + outputStream.write(byteArray, 0, readBytes); + } + LOG.debug("Write " + counter + " bytes to ouput stream"); + } + catch (IOException ex) + { + LOG.error("Error on read/write ", ex); + throw new TransformerException(ex); + } + } + // not StreamResult + else + { + XMLReader xmlReader = null; + try + { + xmlReader = getXMLReader(); + LOG.debug("xmlReader class is " + xmlReader.getClass().getName()); + + // set default resolver + if (resolvingService != null) + { + xmlReader.setEntityResolver(resolvingService.getEntityResolver()); + LOG.debug("Set entity resolver"); + } + + // SAXResult use XMLReader to parce InputStream to SAXEvents + if (result instanceof SAXResult) + { + SAXResult saxResult = (SAXResult)result; + xmlReader.setContentHandler(saxResult.getHandler()); + LOG.debug("Parse direct to result"); + } + + // not StreamResult, not SAXResult - create empty transformation + else + { + LOG.debug("Create empty transformation"); + TransformerHandler transformerHandler = tSAXFactory.newTransformerHandler(); + transformerHandler.setResult(result); + xmlReader.setContentHandler(transformerHandler); + LOG.debug("Parse to result throw empty transformer"); + } + xmlReader.parse(new InputSource(input)); + LOG.debug("Parse complete"); + } + catch (SAXException ex) + { + throw new TransformerException(ex); + } + catch (IOException ex) + { + throw new TransformerException(ex); + } + } + } + + /** + * Transform javax.xml.transform.Source to java.io.InputStream if can't + * transform throw exception + * + * @param source Source + * @return InputStream + * @throws NotSupportedIOTypeException + */ + protected InputStream sourceAsInputStream(Source source) throws NotSupportedIOTypeException + { + InputSource inputSource = SAXSource.sourceToInputSource(source); + if (inputSource == null) + { + throw new NotSupportedIOTypeException(source); + } + return inputSource.getByteStream(); + } + + /** + * TODO REMOVE!!!! For debug only!!! + * @deprecated see Warning + */ + protected void writeTofile(byte[] bytes, String postfix) + { + String POSTFIX = new java.text.SimpleDateFormat("yy-MM-DD_HH-mm-ss_").format(new java.util.Date()); + try + { + + java.io.FileOutputStream fileLog = + new java.io.FileOutputStream("c:/tmp/transf" + POSTFIX + postfix + ".xhtml"); + fileLog.write(bytes); + fileLog.flush(); + fileLog.close(); + + } + catch (java.io.FileNotFoundException ex) + { + if (LOG.isTraceEnabled()) + { + LOG.trace("An exception occurred: " + ex.getMessage()); + } + } + catch (IOException ex) + { + if (LOG.isTraceEnabled()) + { + LOG.trace("An exception occurred: " + ex.getMessage()); + } + } + } + +} diff --git a/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/transform/impl/trax/TRAXTemplatesImpl.java b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/transform/impl/trax/TRAXTemplatesImpl.java new file mode 100644 index 0000000000..db6563327e --- /dev/null +++ b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/transform/impl/trax/TRAXTemplatesImpl.java @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2009 eXo Platform SAS. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.exoplatform.services.xml.transform.impl.trax; + +import org.exoplatform.services.xml.resolving.XMLResolvingService; +import org.exoplatform.services.xml.transform.trax.TRAXTemplates; +import org.exoplatform.services.xml.transform.trax.TRAXTransformer; + +import java.util.Properties; + +import javax.xml.transform.Templates; +import javax.xml.transform.TransformerConfigurationException; + +/** + * Created by The eXo Platform SAS . Wrapper for Trax Transformer. + * + * @author Alexander Kravchuk + * @version $Id: TRAXTemplatesImpl.java 5799 2006-05-28 17:55:42Z geaz $ + */ + +public class TRAXTemplatesImpl implements TRAXTemplates +{ + private Templates templates; + + private XMLResolvingService resolvingService; + + public TRAXTemplatesImpl(Templates templates) + { + this.templates = templates; + } + + public Properties getOutputProperties() + { + return templates.getOutputProperties(); + } + + public TRAXTransformer newTransformer() throws TransformerConfigurationException + { + TRAXTransformerImpl transf = new TRAXTransformerImpl(this.templates); + transf.setResolvingService(resolvingService); + return transf; + } + + public void setResolvingService(XMLResolvingService r) + { + resolvingService = r; + } +} diff --git a/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/transform/impl/trax/TRAXTemplatesLoaderPlugin.java b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/transform/impl/trax/TRAXTemplatesLoaderPlugin.java new file mode 100644 index 0000000000..68a3b34245 --- /dev/null +++ b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/transform/impl/trax/TRAXTemplatesLoaderPlugin.java @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2009 eXo Platform SAS. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.exoplatform.services.xml.transform.impl.trax; + +import org.exoplatform.container.component.BaseComponentPlugin; +import org.exoplatform.container.xml.InitParams; +import org.exoplatform.container.xml.PropertiesParam; + +import java.util.HashMap; +import java.util.Map; + +/** + * @author Andrey Parfonov + * @version $Id: $ + */ +public class TRAXTemplatesLoaderPlugin extends BaseComponentPlugin +{ + + private Map templates_ = new HashMap(); + + public TRAXTemplatesLoaderPlugin(InitParams params) throws Exception + { + if (params != null) + { + PropertiesParam pparams = params.getPropertiesParam("xsl-source-urls"); + if (pparams != null) + templates_ = pparams.getProperties(); + } + } + + public Map getTRAXTemplates() + { + return templates_; + } + +} diff --git a/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/transform/impl/trax/TRAXTemplatesServiceImpl.java b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/transform/impl/trax/TRAXTemplatesServiceImpl.java new file mode 100644 index 0000000000..9dfa88f4b2 --- /dev/null +++ b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/transform/impl/trax/TRAXTemplatesServiceImpl.java @@ -0,0 +1,162 @@ +/* + * Copyright (C) 2009 eXo Platform SAS. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.exoplatform.services.xml.transform.impl.trax; + +import org.exoplatform.container.component.ComponentPlugin; +import org.exoplatform.services.log.ExoLogger; +import org.exoplatform.services.log.Log; +import org.exoplatform.services.xml.transform.NotSupportedIOTypeException; +import org.exoplatform.services.xml.transform.trax.TRAXTemplates; +import org.exoplatform.services.xml.transform.trax.TRAXTemplatesService; +import org.exoplatform.services.xml.transform.trax.TRAXTransformerService; +import org.picocontainer.Startable; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import javax.xml.transform.Source; +import javax.xml.transform.TransformerException; +import javax.xml.transform.stream.StreamSource; + +/** + * @author Andrey Parfonov + * @version $Id: $ + */ +public class TRAXTemplatesServiceImpl implements TRAXTemplatesService, Startable +{ + + private static final Log LOG = ExoLogger.getLogger("exo.core.component.xml-processing.TRAXTemplatesServiceImpl"); + + private Map templates_; + + private TRAXTransformerService traxTransformerService_; + + public TRAXTemplatesServiceImpl(TRAXTransformerService traxTransformerService) + { + traxTransformerService_ = traxTransformerService; + templates_ = new HashMap(); + } + + /* + * (non-Javadoc) + * @see + * org.exoplatform.services.xml.transform.trax.TRAXTemplatesService#getTemplates + * ( java.lang.String) + */ + public TRAXTemplates getTemplates(String key) + { + return templates_.get(key); + } + + /* + * (non-Javadoc) + * @seeorg.exoplatform.services.xml.transform.trax.TRAXTemplatesService# + * addTRAXTemplates( java.lang.String, + * org.exoplatform.services.xml.transform.trax.TRAXTemplates) + */ + public void addTRAXTemplates(String key, TRAXTemplates templates) throws IllegalArgumentException + { + if (templates_.get(key) != null) + { + throw new IllegalArgumentException("Templates with key '" + key + "' already exists!"); + } + templates_.put(key, templates); + } + + /* + * (non-Javadoc) + * @seeorg.exoplatform.services.xml.transform.trax.TRAXTemplatesService# + * addTRAXTemplates( java.lang.String, javax.xml.transform.Source) + */ + public void addTRAXTemplates(String key, Source source) throws IllegalArgumentException + { + if (templates_.get(key) != null) + { + throw new IllegalArgumentException("Templates with key '" + key + "' already exists!"); + } + try + { + templates_.put(key, traxTransformerService_.getTemplates(source)); + } + catch (NotSupportedIOTypeException e) + { + throw new IllegalArgumentException("Source has unsupported context." + e, e); + } + catch (TransformerException e) + { + throw new IllegalArgumentException("Can't get templates from source." + e, e); + } + } + + public void addPlugin(ComponentPlugin plugin) + { + if (plugin instanceof TRAXTemplatesLoaderPlugin) + { + Map m = ((TRAXTemplatesLoaderPlugin)plugin).getTRAXTemplates(); + Set keys = m.keySet(); + for (String key : keys) + { + String xsltSchema = m.get(key); + try + { + if (Thread.currentThread().getContextClassLoader().getResource(xsltSchema) != null) + { + LOG.info("XSLT schema found by relative path: " + xsltSchema); + addTRAXTemplates(key, traxTransformerService_.getTemplates(new StreamSource(Thread.currentThread().getContextClassLoader() + .getResourceAsStream(xsltSchema)))); + } + else + LOG.error("XSLT schema not found: " + xsltSchema); + } + catch (IllegalArgumentException e) + { + LOG.error("Add new TRAXTemplates failed : " + e.getMessage()); + } + catch (TransformerException e) + { + LOG.error("Add new TRAXTemplates failed : " + e.getMessage()); + } + catch (NotSupportedIOTypeException e) + { + LOG.error("Add new TRAXTemplates failed : " + e.getMessage()); + } + } + } + } + + // ------ Startable ------- + + /* + * (non-Javadoc) + * @see org.picocontainer.Startable#start() + */ + public void start() + { + } + + /* + * (non-Javadoc) + * @see org.picocontainer.Startable#stop() + */ + public void stop() + { + } + +} diff --git a/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/transform/impl/trax/TRAXTransformerImpl.java b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/transform/impl/trax/TRAXTransformerImpl.java new file mode 100644 index 0000000000..ea1e42d877 --- /dev/null +++ b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/transform/impl/trax/TRAXTransformerImpl.java @@ -0,0 +1,228 @@ +/* + * Copyright (C) 2009 eXo Platform SAS. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.exoplatform.services.xml.transform.impl.trax; + +import org.exoplatform.services.xml.transform.NotSupportedIOTypeException; +import org.exoplatform.services.xml.transform.impl.TransformerBase; +import org.exoplatform.services.xml.transform.trax.TRAXTransformer; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.XMLReader; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.Properties; + +import javax.xml.transform.ErrorListener; +import javax.xml.transform.Result; +import javax.xml.transform.Source; +import javax.xml.transform.Templates; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.transform.URIResolver; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.sax.SAXResult; +import javax.xml.transform.sax.SAXSource; +import javax.xml.transform.sax.SAXTransformerFactory; +import javax.xml.transform.sax.TransformerHandler; +import javax.xml.transform.stream.StreamResult; + +/** + * Created by The eXo Platform SAS . Implementation of Trax Transformer + * interface + * + * @author Gennady Azarenkov + * @author Alexander Kravchuk + * @version $Id: TRAXTransformerImpl.java 5799 2006-05-28 17:55:42Z geaz $ + */ + +public class TRAXTransformerImpl extends TransformerBase implements TRAXTransformer +{ + + protected TransformerHandler tHandler; + + protected Transformer getTransformer() + { + return tHandler.getTransformer(); + } + + public TRAXTransformerImpl() throws TransformerConfigurationException + { + SAXTransformerFactory saxTFactory = (SAXTransformerFactory)SAXTransformerFactory.newInstance(); + tHandler = saxTFactory.newTransformerHandler(); + } + + public TRAXTransformerImpl(final Source source) throws TransformerConfigurationException + { + final SAXTransformerFactory saxTFactory = (SAXTransformerFactory)SAXTransformerFactory.newInstance(); + + tHandler = saxTFactory.newTransformerHandler(source); + + } + + public TRAXTransformerImpl(Templates templates) throws TransformerConfigurationException + { + SAXTransformerFactory saxTFactory = (SAXTransformerFactory)SAXTransformerFactory.newInstance(); + tHandler = saxTFactory.newTransformerHandler(templates); + } + + @Override + protected void internalTransform(Source source) throws TransformerException, NotSupportedIOTypeException, + IllegalStateException + { + + XMLReader xmlReader = null; + + try + { + // xmlReader = XMLReaderFactory. + // createXMLReader("org.apache.xerces.parsers.SAXParser"); + xmlReader = getXMLReader(); + // set default resolver + if (resolvingService != null) + { + xmlReader.setEntityResolver(resolvingService.getEntityResolver()); + LOG.debug("Set entity resolver"); + } + } + catch (SAXException ex) + { + throw new TransformerException(ex); + } + + xmlReader.setContentHandler(tHandler); + // tHandler.setResult(getResult()); + + InputSource inputSource = null; + // todo simplify + // SAXSource.sourceToInputSource(Source source) from JSDK does not supported + // DOMSource + if (source instanceof DOMSource) + { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + SAXTransformerFactory.newInstance().newTransformer().transform(source, new StreamResult(outputStream)); + inputSource = new InputSource(new ByteArrayInputStream(outputStream.toByteArray())); + } + else + { + inputSource = SAXSource.sourceToInputSource(source); + } + if (inputSource == null) + { + throw new NotSupportedIOTypeException(source); + } + + try + { + final XMLReader fXMLReader = xmlReader; + final InputSource fInputSource = inputSource; + fXMLReader.parse(fInputSource); + } + catch (Exception e) + { + Throwable cause = e.getCause(); + if (cause instanceof SAXException) + { + throw new TransformerException(cause); + } + else if (cause instanceof IOException) + { + throw new TransformerException(cause); + } + else if (cause instanceof RuntimeException) + { + throw (RuntimeException)cause; + } + else + { + throw new RuntimeException(cause); + } + } + } + + @Override + protected void afterInitResult() + { + tHandler.setResult(getResult()); + } + + // delegation to Transformer, see getTransformer() + public Result getTransformerAsResult() + { + return new SAXResult(tHandler); + } + + public Object getParameter(String param) + { + return getTransformer().getParameter(param); + } + + public void setParameter(String name, Object value) + { + getTransformer().setParameter(name, value); + } + + public void clearParameters() + { + getTransformer().clearParameters(); + } + + public String getOutputProperty(String prop) + { + return getTransformer().getOutputProperty(prop); + } + + public void setOutputProperty(String name, String value) + { + getTransformer().setOutputProperty(name, value); + } + + public void setOutputProperties(Properties props) + { + getTransformer().setOutputProperties(props); + } + + public Properties getOutputProperties() + { + return getTransformer().getOutputProperties(); + } + + public URIResolver getURIResolver() + { + return getTransformer().getURIResolver(); + } + + public void setURIResolver(URIResolver resolver) + { + getTransformer().setURIResolver(resolver); + } + + public ErrorListener getErrorListener() + { + return getTransformer().getErrorListener(); + } + + public void setErrorListener(ErrorListener listener) + { + getTransformer().setErrorListener(listener); + } + +} diff --git a/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/transform/impl/trax/TRAXTransformerServiceImpl.java b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/transform/impl/trax/TRAXTransformerServiceImpl.java new file mode 100644 index 0000000000..f75df317ec --- /dev/null +++ b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/transform/impl/trax/TRAXTransformerServiceImpl.java @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2009 eXo Platform SAS. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.exoplatform.services.xml.transform.impl.trax; + +import org.exoplatform.services.xml.resolving.XMLResolvingService; +import org.exoplatform.services.xml.transform.NotSupportedIOTypeException; +import org.exoplatform.services.xml.transform.trax.TRAXTemplates; +import org.exoplatform.services.xml.transform.trax.TRAXTransformer; +import org.exoplatform.services.xml.transform.trax.TRAXTransformerService; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.XMLReader; + +import java.io.IOException; + +import javax.xml.transform.Source; +import javax.xml.transform.Templates; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.transform.sax.SAXSource; +import javax.xml.transform.sax.SAXTransformerFactory; +import javax.xml.transform.sax.TemplatesHandler; + +/** + * Created by The eXo Platform SAS . + * + * @author Gennady Azarenkov + * @author Alexander Kravchuk + * @version $Id: TRAXTransformerServiceImpl.java 5799 2006-05-28 17:55:42Z geaz + * $ + */ + +public class TRAXTransformerServiceImpl implements TRAXTransformerService +{ + + private XMLResolvingService resolvingService; + + public TRAXTransformerServiceImpl(XMLResolvingService resolvingService) + { + this.resolvingService = resolvingService; + } + + public TRAXTransformer getTransformer() throws TransformerConfigurationException + { + TRAXTransformerImpl transf = new TRAXTransformerImpl(); + transf.setResolvingService(resolvingService); + return transf; + } + + public TRAXTransformer getTransformer(Source source) throws TransformerConfigurationException + { + TRAXTransformerImpl transf = new TRAXTransformerImpl(source); + transf.setResolvingService(resolvingService); + return transf; + } + + public TRAXTemplates getTemplates(Source source) throws TransformerException, NotSupportedIOTypeException + { + TRAXTemplatesImpl templates = new TRAXTemplatesImpl(getXSLTemplates(source)); + templates.setResolvingService(resolvingService); + return templates; + } + + private Templates getXSLTemplates(Source source) throws TransformerException, NotSupportedIOTypeException + { + SAXTransformerFactory saxTFactory = (SAXTransformerFactory)SAXTransformerFactory.newInstance(); + + TemplatesHandler templateHandler = saxTFactory.newTemplatesHandler(); + XMLReader xmlReader; + try + { + // xmlReader = XMLReaderFactory. + // createXMLReader("org.apache.xerces.parsers.SAXParser"); + xmlReader = TRAXTransformerImpl.getXMLReader(); + // set default resolver + if (resolvingService != null) + { + xmlReader.setEntityResolver(resolvingService.getEntityResolver()); + } + + } + catch (SAXException ex) + { + throw new TransformerException(ex); + } + + xmlReader.setContentHandler(templateHandler); + InputSource inputSource = SAXSource.sourceToInputSource(source); + if (inputSource == null) + { + throw new NotSupportedIOTypeException(source); + } + + try + { + xmlReader.parse(inputSource); + } + catch (SAXException ex) + { + throw new TransformerException(ex); + } + catch (IOException ex) + { + throw new TransformerException(ex); + } + + return templateHandler.getTemplates(); + + } + +} diff --git a/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/transform/trax/Constants.java b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/transform/trax/Constants.java new file mode 100644 index 0000000000..83e23dda7d --- /dev/null +++ b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/transform/trax/Constants.java @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2009 eXo Platform SAS. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.exoplatform.services.xml.transform.trax; + +/** + * Created by The eXo Platform SAS . + * + * @author Gennady Azarenkov + * @version $Id: Constants.java 5799 2006-05-28 17:55:42Z geaz $ + */ + +public class Constants +{ + public static final String XSLT_DIR = "xslt"; + + public static final String DOCBOOK_TO_HTML_STYLE = XSLT_DIR + "/docbook/html/docbook.xsl"; + + public static final String DOCBOOK_TO_FO_STYLE = XSLT_DIR + "/docbook/fo/docbook.xsl"; +} diff --git a/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/transform/trax/TRAXTemplates.java b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/transform/trax/TRAXTemplates.java new file mode 100644 index 0000000000..7415818f35 --- /dev/null +++ b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/transform/trax/TRAXTemplates.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2009 eXo Platform SAS. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.exoplatform.services.xml.transform.trax; + +import java.util.Properties; + +import javax.xml.transform.TransformerConfigurationException; + +/** + * Created by The eXo Platform SAS . An object that implements this interface is + * the runtime representation of processed transformation instructions Analog of + * javax.xml.transform.Templates + * + * @author Alexander Kravchuk + * @version $Id: TRAXTemplates.java 5799 2006-05-28 17:55:42Z geaz $ + * @see javax.xml.transform.Templates + */ +public interface TRAXTemplates +{ + + /** + * @see javax.xml.transform.Templates#getOutputProperties() + */ + Properties getOutputProperties(); + + TRAXTransformer newTransformer() throws TransformerConfigurationException; + +} diff --git a/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/transform/trax/TRAXTemplatesService.java b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/transform/trax/TRAXTemplatesService.java new file mode 100644 index 0000000000..f95bb62142 --- /dev/null +++ b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/transform/trax/TRAXTemplatesService.java @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2009 eXo Platform SAS. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.exoplatform.services.xml.transform.trax; + +import javax.xml.transform.Source; + +/** + * @author Andrey Parfonov + * @version $Id: $ + */ +public interface TRAXTemplatesService +{ + + /** + * Add new TRAXTemplates to the service. + * + * @param key the key for this templates. + * @param templates the TRAXTemplates. + * @throws IllegalArgumentException + */ + void addTRAXTemplates(String key, TRAXTemplates templates) throws IllegalArgumentException; + + /** + * Add new TRAXTemplates to the service from javax.xml.transform.Source. + * + * @param key the key for this templates. + * @param source the TRAXTemplates. + * @throws IllegalArgumentException + */ + void addTRAXTemplates(String key, Source source) throws IllegalArgumentException; + + /** + * Get templates by key. + * + * @param key the key. + * @return the TRAXTemplates or null. + */ + TRAXTemplates getTemplates(String key); + +} diff --git a/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/transform/trax/TRAXTransformer.java b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/transform/trax/TRAXTransformer.java new file mode 100644 index 0000000000..ea9b226900 --- /dev/null +++ b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/transform/trax/TRAXTransformer.java @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2009 eXo Platform SAS. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.exoplatform.services.xml.transform.trax; + +import org.exoplatform.services.xml.transform.PipeTransformer; + +import java.util.Properties; + +import javax.xml.transform.ErrorListener; +import javax.xml.transform.URIResolver; + +/** + * Created by The eXo Platform SAS. + * + * @author Gennady Azarenkov + * @author Alexander Kravchuk + * @version $Id: TRAXTransformer.java 5799 2006-05-28 17:55:42Z geaz $ + */ +public interface TRAXTransformer extends PipeTransformer +{ + /** + * @see javax.xml.transform.Transformer#getParameter(java.lang.String) + */ + Object getParameter(String param); + + /** + * @see javax.xml.transform.Transformer#setParameter(java.lang.String, + * java.lang.Object) + */ + void setParameter(String name, Object value); + + /** + * @see javax.xml.transform.Transformer#clearParameters() + */ + void clearParameters(); + + /** + * @see javax.xml.transform.Transformer#getOutputProperty(java.lang.String) + */ + String getOutputProperty(String prop); + + /** + * @see javax.xml.transform.Transformer#setOutputProperty(java.lang.String, + * java.lang.String) + */ + void setOutputProperty(String name, String value); + + /** + * @see javax.xml.transform.Transformer#setOutputProperties(java.util.Properties) + */ + void setOutputProperties(Properties props); + + /** + * @see javax.xml.transform.Transformer#getOutputProperties() + */ + Properties getOutputProperties(); + + /** + * @see javax.xml.transform.Transformer#getURIResolver() + */ + URIResolver getURIResolver(); + + /** + * @see javax.xml.transform.Transformer#setURIResolver(javax.xml.transform.URIResolver) + */ + void setURIResolver(URIResolver resolver); + + /** + * @see javax.xml.transform.Transformer#getErrorListener() + */ + ErrorListener getErrorListener(); + + /** + * @see javax.xml.transform.Transformer#setErrorListener(javax.xml.transform.ErrorListener) + */ + void setErrorListener(ErrorListener listener); + +} diff --git a/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/transform/trax/TRAXTransformerService.java b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/transform/trax/TRAXTransformerService.java new file mode 100644 index 0000000000..3e2facfec4 --- /dev/null +++ b/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/xml/transform/trax/TRAXTransformerService.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2009 eXo Platform SAS. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.exoplatform.services.xml.transform.trax; + +import org.exoplatform.container.spi.DefinitionByType; +import org.exoplatform.services.xml.transform.NotSupportedIOTypeException; +import org.exoplatform.services.xml.transform.impl.trax.TRAXTransformerServiceImpl; + +import javax.xml.transform.Source; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; + +/** + * Created by The eXo Platform SAS . + * + * @author Gennady Azarenkov + * @author Alexander Kravchuk + * @version $Id: TRAXTransformerService.java 5799 2006-05-28 17:55:42Z geaz $ + */ +@DefinitionByType(type = TRAXTransformerServiceImpl.class) +public interface TRAXTransformerService +{ + TRAXTransformer getTransformer() throws TransformerConfigurationException; + + TRAXTransformer getTransformer(Source source) throws TransformerConfigurationException; + + TRAXTemplates getTemplates(Source source) throws TransformerException, NotSupportedIOTypeException; +} diff --git a/exo.jcr.component.webdav/src/main/resources/CatalogManager.properties b/exo.jcr.component.webdav/src/main/resources/CatalogManager.properties new file mode 100644 index 0000000000..984089fb0a --- /dev/null +++ b/exo.jcr.component.webdav/src/main/resources/CatalogManager.properties @@ -0,0 +1,9 @@ +#CatalogManager.properties +verbosity=1 +relative-catalogs=yes +# Always use semicolons in this list /xcatalog;/share/doctypes/catalog +catalogs=catalog/exo-catalog.xml +prefer=public +static-catalog=yes +allow-oasis-xml-catalog-pi=yes +catalog-class-name=org.apache.xml.resolver.Resolver diff --git a/exo.jcr.component.webdav/src/main/resources/catalog/exo-catalog.xml b/exo.jcr.component.webdav/src/main/resources/catalog/exo-catalog.xml new file mode 100644 index 0000000000..ac3009a2fa --- /dev/null +++ b/exo.jcr.component.webdav/src/main/resources/catalog/exo-catalog.xml @@ -0,0 +1,29 @@ + + + + + + + + + + diff --git a/exo.jcr.component.webdav/src/main/resources/conf/configuration.xml b/exo.jcr.component.webdav/src/main/resources/conf/configuration.xml new file mode 100644 index 0000000000..8f9aa4cf09 --- /dev/null +++ b/exo.jcr.component.webdav/src/main/resources/conf/configuration.xml @@ -0,0 +1,89 @@ + + + + + org.exoplatform.services.xml.resolving.impl.XMLResolvingServiceImpl + + + add.resolving.table + addPlugin + org.exoplatform.services.xml.resolving.impl.AddXMLResolvingContextPlugin + + + xhtml1-transitional.dtd + + + + + + web-app_2_3.dtd + + + + + + datatypes.dtd + + + + + XMLSchema.dtd + + + + + + xhtml1-frameset.dtd + + + + + + xhtml1-strict.dtd + + + + + + xhtml-lat1.ent + + + + + + xhtml-special.ent + + + + + + xhtml-symbol.ent + + + + + + + + + diff --git a/exo.jcr.component.webdav/src/main/resources/conf/portal/configuration.xml b/exo.jcr.component.webdav/src/main/resources/conf/portal/configuration.xml index c4ebfe82e0..876782927e 100644 --- a/exo.jcr.component.webdav/src/main/resources/conf/portal/configuration.xml +++ b/exo.jcr.component.webdav/src/main/resources/conf/portal/configuration.xml @@ -27,6 +27,76 @@ org.exoplatform.services.jcr.webdav.lnkproducer.LnkProducer + + org.exoplatform.services.xml.transform.impl.trax.TRAXTemplatesServiceImpl + + + + org.exoplatform.services.xml.resolving.impl.XMLResolvingServiceImpl + + + add.resolving.table + addPlugin + org.exoplatform.services.xml.resolving.impl.AddXMLResolvingContextPlugin + + + xhtml1-transitional.dtd + + + + + + web-app_2_3.dtd + + + + + + datatypes.dtd + + + + + XMLSchema.dtd + + + + + + xhtml1-frameset.dtd + + + + + + xhtml1-strict.dtd + + + + + + xhtml-lat1.ent + + + + + + xhtml-special.ent + + + + + + xhtml-symbol.ent + + + + + + + + + org.exoplatform.services.xml.transform.impl.trax.TRAXTemplatesServiceImpl diff --git a/exo.jcr.component.webdav/src/main/resources/dtd/XMLSchema.dtd b/exo.jcr.component.webdav/src/main/resources/dtd/XMLSchema.dtd new file mode 100644 index 0000000000..9e57dda975 --- /dev/null +++ b/exo.jcr.component.webdav/src/main/resources/dtd/XMLSchema.dtd @@ -0,0 +1,402 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +%xs-datatypes; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/exo.jcr.component.webdav/src/main/resources/dtd/datatypes.dtd b/exo.jcr.component.webdav/src/main/resources/dtd/datatypes.dtd new file mode 100644 index 0000000000..3547e11a76 --- /dev/null +++ b/exo.jcr.component.webdav/src/main/resources/dtd/datatypes.dtd @@ -0,0 +1,203 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/exo.jcr.component.webdav/src/main/resources/dtd/j2ee_1_4.xsd b/exo.jcr.component.webdav/src/main/resources/dtd/j2ee_1_4.xsd new file mode 100644 index 0000000000..e19c16dcca --- /dev/null +++ b/exo.jcr.component.webdav/src/main/resources/dtd/j2ee_1_4.xsd @@ -0,0 +1,1674 @@ + + + + + @(#)j2ee_1_4.xsds 1.43 03/09/16 + + + + + + + Copyright 2003 Sun Microsystems, Inc., 901 San Antonio + Road, Palo Alto, California 94303, U.S.A. All rights + reserved. + + Sun Microsystems, Inc. has intellectual property rights + relating to technology described in this document. In + particular, and without limitation, these intellectual + property rights may include one or more of the U.S. patents + listed at http://www.sun.com/patents and one or more + additional patents or pending patent applications in the + U.S. and other countries. + + This document and the technology which it describes are + distributed under licenses restricting their use, copying, + distribution, and decompilation. No part of this document + may be reproduced in any form by any means without prior + written authorization of Sun and its licensors, if any. + + Third-party software, including font technology, is + copyrighted and licensed from Sun suppliers. + + Sun, Sun Microsystems, the Sun logo, Solaris, Java, J2EE, + JavaServer Pages, Enterprise JavaBeans and the Java Coffee + Cup logo are trademarks or registered trademarks of Sun + Microsystems, Inc. in the U.S. and other countries. + + Federal Acquisitions: Commercial Software - Government Users + Subject to Standard License Terms and Conditions. + + + + + + + +The following definitions that appear in the common +shareable schema(s) of J2EE deployment descriptors should be +interpreted with respect to the context they are included: + +Deployment Component may indicate one of the following: + j2ee application; + application client; + web application; + enterprise bean; + resource adapter; + +Deployment File may indicate one of the following: + ear file; + war file; + jar file; + rar file; + + + + + + + + + + + + + + + + This group keeps the usage of the contained description related + elements consistent across J2EE deployment descriptors. + + All elements may occur multiple times with different languages, + to support localization of the content. + + + + + + + + + + + + + + + + + + The description type is used by a description element to + provide text describing the parent element. The elements + that use this type should include any information that the + Deployment Component's Deployment File file producer wants + to provide to the consumer of the Deployment Component's + Deployment File (i.e., to the Deployer). Typically, the + tools used by such a Deployment File consumer will display + the description when processing the parent element that + contains the description. + + The lang attribute defines the language that the + description is provided in. The default value is "en" (English). + + + + + + + + + + + + + + + + + + This type defines a dewey decimal which is used + to describe versions of documents. + + + + + + + + + + + + + + + + + + Employee Self Service + + The value of the xml:lang attribute is "en" (English) by default. + + ]]> + + + + + + + + + + + + + + + + EmployeeRecord + + ../products/product.jar#ProductEJB + + ]]> + + + + + + + + + + + + + + + + The ejb-local-refType is used by ejb-local-ref elements for + the declaration of a reference to an enterprise bean's local + home. The declaration consists of: + + - an optional description + - the EJB reference name used in the code of the Deployment + Component that's referencing the enterprise bean + - the expected type of the referenced enterprise bean + - the expected local home and local interfaces of the + referenced enterprise bean + - optional ejb-link information, used to specify the + referenced enterprise bean + + + + + + + + + + + + + + + + + + + + + + + ejb/Payroll + + ]]> + + + + + + + + + + + + + + The ejb-ref-typeType contains the expected type of the + referenced enterprise bean. + + The ejb-ref-type designates a value + that must be one of the following: + + Entity + Session + + + + + + + + + + + + + + + + + + + + The ejb-refType is used by ejb-ref elements for the + declaration of a reference to an enterprise bean's home. The + declaration consists of: + + - an optional description + - the EJB reference name used in the code of + the Deployment Component that's referencing the enterprise + bean + - the expected type of the referenced enterprise bean + - the expected home and remote interfaces of the referenced + enterprise bean + - optional ejb-link information, used to specify the + referenced enterprise bean + + + + + + + + + + + + + + + + + + + + + + + + This type is used to designate an empty + element when used. + + + + + + + + + + + + java.lang.Boolean + + ]]> + + + + + + + + + + + + + + + + + + + + + + + + + + The env-entryType is used to declare an application's + environment entry. The declaration consists of an optional + description, the name of the environment entry, and an + optional value. If a value is not specified, one must be + supplied during deployment. + + It is used by env-entry elements. + + + + + + + + + + + minAmount + + ]]> + + + + + + + + + + + 100.00 + + ]]> + + + + + + + + + + + + + + + The elements that use this type designate the name of a + Java class or interface. The name is in the form of a + "binary name", as defined in the JLS. This is the form + of name used in Class.forName(). Tools that need the + canonical name (the name used in source code) will need + to convert this binary name to the canonical name. + + + + + + + + + + + + + + + + This type defines four different values which can designate + boolean values. This includes values yes and no which are + not designated by xsd:boolean + + + + + + + + + + + + + + + + + + + + + com.aardvark.payroll.PayrollHome + + ]]> + + + + + + + + + + + + + + + The icon type contains small-icon and large-icon elements + that specify the file names for small and large GIF or + JPEG icon images used to represent the parent element in a + GUI tool. + + The xml:lang attribute defines the language that the + icon file names are provided in. Its value is "en" (English) + by default. + + + + + + + + + employee-service-icon16x16.jpg + + ]]> + + + + + + + + employee-service-icon32x32.jpg + + ]]> + + + + + + + + + + + + + + + + + + + + The java-identifierType defines a Java identifier. + The users of this type should further verify that + the content does not contain Java reserved keywords. + + + + + + + + + + + + + + + + + + This is a generic type that designates a Java primitive + type or a fully qualified name of a Java interface/type, + or an array of such types. + + + + + + + + + + + + + + + + + + The jndi-nameType type designates a JNDI name in the + Deployment Component's environment and is relative to the + java:comp/env context. A JNDI name must be unique within the + Deployment Component. + + + + + + + + + + + + + + + + This group keeps the usage of the contained JNDI environment + reference elements consistent across J2EE deployment descriptors. + + + + + + + + + + + + + + + + + + + + + + + The listenerType indicates the deployment properties for a web + application listener bean. + + + + + + + + + + + The listener-class element declares a class in the + application must be registered as a web + application listener bean. The value is the fully + qualified classname of the listener class. + + + + + + + + + + + + + + + + The local-homeType defines the fully-qualified + name of an enterprise bean's local home interface. + + + + + + + + + + + + + + + The localType defines the fully-qualified name of an + enterprise bean's local interface. + + + + + + + + + + + + + + + + The message-destination-linkType is used to link a message + destination reference or message-driven bean to a message + destination. + + The Assembler sets the value to reflect the flow of messages + between producers and consumers in the application. + + The value must be the message-destination-name of a message + destination in the same Deployment File or in another + Deployment File in the same J2EE application unit. + + Alternatively, the value may be composed of a path name + specifying a Deployment File containing the referenced + message destination with the message-destination-name of the + destination appended and separated from the path name by + "#". The path name is relative to the Deployment File + containing Deployment Component that is referencing the + message destination. This allows multiple message + destinations with the same name to be uniquely identified. + + + + + + + + + + + + + + + + + jms/StockQueue + + javax.jms.Queue + + Consumes + + CorporateStocks + + + + ]]> + + + + + + + + + The message-destination-ref-name element specifies + the name of a message destination reference; its + value is the environment entry name used in + Deployment Component code. The name is a JNDI name + relative to the java:comp/env context and must be + unique within an ejb-jar (for enterprise beans) or a + Deployment File (for others). + + + + + + + + + + + + + + + + + + javax.jms.Queue + + + ]]> + + + + + + + + + + + + + + + The message-destination-usageType specifies the use of the + message destination indicated by the reference. The value + indicates whether messages are consumed from the message + destination, produced for the destination, or both. The + Assembler makes use of this information in linking producers + of a destination with its consumers. + + The value of the message-destination-usage element must be + one of the following: + Consumes + Produces + ConsumesProduces + + + + + + + + + + + + + + + + + + + + CorporateStocks + + + + ]]> + + + + + + + + + + The message-destination-name element specifies a + name for a message destination. This name must be + unique among the names of message destinations + within the Deployment File. + + + + + + + + + + + + + + + + This type is a general type that can be used to declare + parameter/value lists. + + + + + + + + + + + The param-name element contains the name of a + parameter. + + + + + + + + + + The param-value element contains the value of a + parameter. + + + + + + + + + + + + + + + + + The elements that use this type designate either a relative + path or an absolute path starting with a "/". + + In elements that specify a pathname to a file within the + same Deployment File, relative filenames (i.e., those not + starting with "/") are considered relative to the root of + the Deployment File's namespace. Absolute filenames (i.e., + those starting with "/") also specify names in the root of + the Deployment File's namespace. In general, relative names + are preferred. The exception is .war files where absolute + names are preferred for consistency with the Servlet API. + + + + + + + + + + + + + + com.wombat.empl.EmployeeService + + ]]> + + + + + + + + + + + + + + + The res-authType specifies whether the Deployment Component + code signs on programmatically to the resource manager, or + whether the Container will sign on to the resource manager + on behalf of the Deployment Component. In the latter case, + the Container uses information that is supplied by the + Deployer. + + The value must be one of the two following: + + Application + Container + + + + + + + + + + + + + + + + + + + The res-sharing-scope type specifies whether connections + obtained through the given resource manager connection + factory reference can be shared. The value, if specified, + must be one of the two following: + + Shareable + Unshareable + + The default value is Shareable. + + + + + + + + + + + + + + + + + + + + jms/StockQueue + + javax.jms.Queue + + + + ]]> + + + + + + + + + + + The resource-env-ref-name element specifies the name + of a resource environment reference; its value is + the environment entry name used in + the Deployment Component code. The name is a JNDI + name relative to the java:comp/env context and must + be unique within a Deployment Component. + + + + + + + + + + The resource-env-ref-type element specifies the type + of a resource environment reference. It is the + fully qualified name of a Java language class or + interface. + + + + + + + + + + + + + + + + jdbc/EmployeeAppDB + javax.sql.DataSource + Container + Shareable + + + ]]> + + + + + + + + + + + The res-ref-name element specifies the name of a + resource manager connection factory reference. + The name is a JNDI name relative to the + java:comp/env context. + The name must be unique within a Deployment File. + + + + + + + + + + + The res-type element specifies the type of the data + source. The type is specified by the fully qualified + Java language class or interface + expected to be implemented by the data source. + + + + + + + + + + + + + + + + + + + + The role-nameType designates the name of a security role. + + The name must conform to the lexical rules for a token. + + + + + + + + + + + + + + + + + + The run-asType specifies the run-as identity to be + used for the execution of a component. It contains an + optional description, and the name of a security role. + + + + + + + + + + + + + + + + + + + The security-role-refType contains the declaration of a + security role reference in a component's or a + Deployment Component's code. The declaration consists of an + optional description, the security role name used in the + code, and an optional link to a security role. If the + security role is not specified, the Deployer must choose an + appropriate security role. + + + + + + + + + + + + The value of the role-name element must be the String used + as the parameter to the + EJBContext.isCallerInRole(String roleName) method or the + HttpServletRequest.isUserInRole(String role) method. + + + + + + + + + + + The role-link element is a reference to a defined + security role. The role-link element must contain + the name of one of the security roles defined in the + security-role elements. + + + + + + + + + + + + + + + + + + This role includes all employees who are authorized + to access the employee service application. + + employee + + + ]]> + + + + + + + + + + + + + + + + + + This is a special string datatype that is defined by J2EE as + a base type for defining collapsed strings. When schemas + require trailing/leading space elimination as well as + collapsing the existing whitespace, this base type may be + used. + + + + + + + + + + + + + + + + + + + This simple type designates a boolean with only two + permissible values + + - true + - false + + + + + + + + + + + + + + + + + + The url-patternType contains the url pattern of the mapping. + It must follow the rules specified in Section 11.2 of the + Servlet API Specification. This pattern is assumed to be in + URL-decoded form and must not contain CR(#xD) or LF(#xA). + If it contains those characters, the container must inform + the developer with a descriptive error message. + The container must preserve all characters including whitespaces. + + + + + + + + + + + + + + + + + This type adds an "id" attribute to xsd:anyURI. + + + + + + + + + + + + + + + + + + This type adds an "id" attribute to xsd:boolean. + + + + + + + + + + + + + + + + + + + This type adds an "id" attribute to xsd:integer. + + + + + + + + + + + + + + + + + + This type adds an "id" attribute to xsd:NMTOKEN. + + + + + + + + + + + + + + + + + + This type adds an "id" attribute to xsd:nonNegativeInteger. + + + + + + + + + + + + + + + + + + This type adds an "id" attribute to xsd:positiveInteger. + + + + + + + + + + + + + + + + + + This type adds an "id" attribute to xsd:QName. + + + + + + + + + + + + + + + + + + This type adds an "id" attribute to xsd:string. + + + + + + + + + + + + diff --git a/exo.jcr.component.webdav/src/main/resources/dtd/j2ee_web_services_client_1_1.xsd b/exo.jcr.component.webdav/src/main/resources/dtd/j2ee_web_services_client_1_1.xsd new file mode 100644 index 0000000000..12160f2339 --- /dev/null +++ b/exo.jcr.component.webdav/src/main/resources/dtd/j2ee_web_services_client_1_1.xsd @@ -0,0 +1,355 @@ + + + + + @(#)j2ee_web_services_client_1_1.xsds 1.10 02/11/03 + + + + + + + Copyright 2002 Sun Microsystems, Inc., 901 San Antonio + Road, Palo Alto, California 94303, U.S.A. All rights + reserved. + + Sun Microsystems, Inc. has intellectual property rights + relating to technology described in this document. In + particular, and without limitation, these intellectual + property rights may include one or more of the U.S. patents + listed at http://www.sun.com/patents and one or more + additional patents or pending patent applications in the + U.S. and other countries. + + This document and the technology which it describes are + distributed under licenses restricting their use, copying, + distribution, and decompilation. No part of this document + may be reproduced in any form by any means without prior + written authorization of Sun and its licensors, if any. + + Third-party software, including font technology, is + copyrighted and licensed from Sun suppliers. + + Sun, Sun Microsystems, the Sun logo, Solaris, Java, J2EE, + JavaServer Pages, Enterprise JavaBeans and the Java Coffee + Cup logo are trademarks or registered trademarks of Sun + Microsystems, Inc. in the U.S. and other countries. + + Federal Acquisitions: Commercial Software - Government Users + Subject to Standard License Terms and Conditions. + + + + + + + (C) Copyright International Business Machines Corporation 2002 + + + + + + + + + + + + The port-component-ref element declares a client dependency + on the container for resolving a Service Endpoint Interface + to a WSDL port. It optionally associates the Service Endpoint + Interface with a particular port-component. This is only used + by the container for a Service.getPort(Class) method call. + + + + + + + + + + + The service-endpoint-interface element defines a fully qualified + Java class that represents the Service Endpoint Interface of a + WSDL port. + + + + + + + + + + + The port-component-link element links a port-component-ref + to a specific port-component required to be made available + by a service reference. + + The value of a port-component-link must be the + port-component-name of a port-component in the same module + or another module in the same application unit. The syntax + for specification follows the syntax defined for ejb-link + in the EJB 2.0 specification. + + + + + + + + + + + + + + + + + + Defines the name of the handler. The name must be unique + within the module. + + + + + + + + + + + + + + + + + + The service-ref element declares a reference to a Web + service. It contains optional description, display name and + icons, a declaration of the required Service interface, + an optional WSDL document location, an optional set + of JAX-RPC mappings, an optional QName for the service element, + an optional set of Service Endpoint Interfaces to be resolved + by the container to a WSDL port, and an optional set of handlers. + + + + + + + + + + + + The service-ref-name element declares logical name that the + components in the module use to look up the Web service. It + is recommended that all service reference names start with + "service/". + + + + + + + + + + + The service-interface element declares the fully qualified class + name of the JAX-RPC Service interface the client depends on. + In most cases the value will be javax.xml.rpc.Service. A JAX-RPC + generated Service Interface class may also be specified. + + + + + + + + + + + The wsdl-file element contains the URI location of a WSDL + file. The location is relative to the root of the module. + + + + + + + + + + The jaxrpc-mapping-file element contains the name of a file that + describes the JAX-RPC mapping between the Java interaces used by + the application and the WSDL description in the wsdl-file. The + file name is a relative path within the module file. + + + + + + + + + + The service-qname element declares the specific WSDL service + element that is being refered to. It is not specified if no + wsdl-file is declared. + + + + + + + + + + + The port-component-ref element declares a client dependency + on the container for resolving a Service Endpoint Interface + to a WSDL port. It optionally associates the Service Endpoint + Interface with a particular port-component. This is only used + by the container for a Service.getPort(Class) method call. + + + + + + + + + + + Declares the handler for a port-component. Handlers can + access the init-param name/value pairs using the + HandlerInfo interface. If port-name is not specified, the + handler is assumed to be associated with all ports of the + service. + + + + + + + + + + + + + + + + Declares the handler for a port-component. Handlers can access the + init-param name/value pairs using the HandlerInfo interface. If + port-name is not specified, the handler is assumed to be associated + with all ports of the service. + + Used in: service-ref + + + + + + + + + + + Defines the name of the handler. The name must be unique + within the module. + + + + + + + + + + Defines a fully qualified class name for the handler + implementation. + + + + + + + + + + + Defines the QName of a SOAP header that will be processed + by the handler. + + + + + + + + + + + The soap-role element contains a SOAP actor definition that + the Handler will play as a role. + + + + + + + + + + + The port-name element defines the WSDL port-name that a + handler should be associated with. + + + + + + + + + diff --git a/exo.jcr.component.webdav/src/main/resources/dtd/jsp_2_0.xsd b/exo.jcr.component.webdav/src/main/resources/dtd/jsp_2_0.xsd new file mode 100644 index 0000000000..c073b701f7 --- /dev/null +++ b/exo.jcr.component.webdav/src/main/resources/dtd/jsp_2_0.xsd @@ -0,0 +1,313 @@ + + + + + @(#)jsp_2_0.xsds 1.17 03/18/03 + + + + + + + Copyright 2003 Sun Microsystems, Inc., 901 San Antonio + Road, Palo Alto, California 94303, U.S.A. All rights + reserved. + + Sun Microsystems, Inc. has intellectual property rights + relating to technology described in this document. In + particular, and without limitation, these intellectual + property rights may include one or more of the U.S. patents + listed at http://www.sun.com/patents and one or more + additional patents or pending patent applications in the + U.S. and other countries. + + This document and the technology which it describes are + distributed under licenses restricting their use, copying, + distribution, and decompilation. No part of this document + may be reproduced in any form by any means without prior + written authorization of Sun and its licensors, if any. + + Third-party software, including font technology, is + copyrighted and licensed from Sun suppliers. + + Sun, Sun Microsystems, the Sun logo, Solaris, Java, J2EE, + JavaServer Pages, Enterprise JavaBeans and the Java Coffee + Cup logo are trademarks or registered trademarks of Sun + Microsystems, Inc. in the U.S. and other countries. + + Federal Acquisitions: Commercial Software - Government Users + Subject to Standard License Terms and Conditions. + + + + + + + + This is the XML Schema for the JSP 2.0 deployment descriptor + types. The JSP 2.0 schema contains all the special + structures and datatypes that are necessary to use JSP files + from a web application. + + The contents of this schema is used by the web-app_2_4.xsd + file to define JSP specific content. + + + + + + + + The following conventions apply to all J2EE + deployment descriptor elements unless indicated otherwise. + + - In elements that specify a pathname to a file within the + same JAR file, relative filenames (i.e., those not + starting with "/") are considered relative to the root of + the JAR file's namespace. Absolute filenames (i.e., those + starting with "/") also specify names in the root of the + JAR file's namespace. In general, relative names are + preferred. The exception is .war files where absolute + names are preferred for consistency with the Servlet API. + + + + + + + + + + + + + + The jsp-configType is used to provide global configuration + information for the JSP files in a web application. It has + two subelements, taglib and jsp-property-group. + + + + + + + + + + + + + + + + + + + The jsp-file element contains the full path to a JSP file + within the web application beginning with a `/'. + + + + + + + + + + + + + + + + The jsp-property-groupType is used to group a number of + files so they can be given global property information. + All files so described are deemed to be JSP files. The + following additional properties can be described: + + - Control whether EL is ignored + - Control whether scripting elements are invalid + - Indicate pageEncoding information. + - Indicate that a resource is a JSP document (XML) + - Prelude and Coda automatic includes. + + + + + + + + + + + + + Can be used to easily set the isELIgnored + property of a group of JSP pages. By default, the + EL evaluation is enabled for Web Applications using + a Servlet 2.4 or greater web.xml, and disabled + otherwise. + + + + + + + + + + The valid values of page-encoding are those of the + pageEncoding page directive. It is a + translation-time error to name different encodings + in the pageEncoding attribute of the page directive + of a JSP page and in a JSP configuration element + matching the page. It is also a translation-time + error to name different encodings in the prolog + or text declaration of a document in XML syntax and + in a JSP configuration element matching the document. + It is legal to name the same encoding through + mulitple mechanisms. + + + + + + + + + Can be used to easily disable scripting in a + group of JSP pages. By default, scripting is + enabled. + + + + + + + + + If true, denotes that the group of resources + that match the URL pattern are JSP documents, + and thus must be interpreted as XML documents. + If false, the resources are assumed to not + be JSP documents, unless there is another + property group that indicates otherwise. + + + + + + + + + + The include-prelude element is a context-relative + path that must correspond to an element in the + Web Application. When the element is present, + the given path will be automatically included (as + in an include directive) at the beginning of each + JSP page in this jsp-property-group. + + + + + + + + + + The include-coda element is a context-relative + path that must correspond to an element in the + Web Application. When the element is present, + the given path will be automatically included (as + in an include directive) at the end of each + JSP page in this jsp-property-group. + + + + + + + + + + + + + + + + The taglibType defines the syntax for declaring in + the deployment descriptor that a tag library is + available to the application. This can be done + to override implicit map entries from TLD files and + from the container. + + + + + + + + + + A taglib-uri element describes a URI identifying a + tag library used in the web application. The body + of the taglib-uri element may be either an + absolute URI specification, or a relative URI. + There should be no entries in web.xml with the + same taglib-uri value. + + + + + + + + + + the taglib-location element contains the location + (as a resource relative to the root of the web + application) where to find the Tag Library + Description file for the tag library. + + + + + + + + + + + diff --git a/exo.jcr.component.webdav/src/main/resources/dtd/web-app_2_3.dtd b/exo.jcr.component.webdav/src/main/resources/dtd/web-app_2_3.dtd new file mode 100644 index 0000000000..5e3ab01c0f --- /dev/null +++ b/exo.jcr.component.webdav/src/main/resources/dtd/web-app_2_3.dtd @@ -0,0 +1,1063 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/exo.jcr.component.webdav/src/main/resources/dtd/web-app_2_4.xsd b/exo.jcr.component.webdav/src/main/resources/dtd/web-app_2_4.xsd new file mode 100644 index 0000000000..e493662058 --- /dev/null +++ b/exo.jcr.component.webdav/src/main/resources/dtd/web-app_2_4.xsd @@ -0,0 +1,1279 @@ + + + + + @(#)web-app_2_4.xsds 1.60 03/08/26 + + + + + + + Copyright 2003 Sun Microsystems, Inc., 901 San Antonio + Road, Palo Alto, California 94303, U.S.A. All rights + reserved. + + Sun Microsystems, Inc. has intellectual property rights + relating to technology described in this document. In + particular, and without limitation, these intellectual + property rights may include one or more of the U.S. patents + listed at http://www.sun.com/patents and one or more + additional patents or pending patent applications in the + U.S. and other countries. + + This document and the technology which it describes are + distributed under licenses restricting their use, copying, + distribution, and decompilation. No part of this document + may be reproduced in any form by any means without prior + written authorization of Sun and its licensors, if any. + + Third-party software, including font technology, is + copyrighted and licensed from Sun suppliers. + + Sun, Sun Microsystems, the Sun logo, Solaris, Java, J2EE, + JavaServer Pages, Enterprise JavaBeans and the Java Coffee + Cup logo are trademarks or registered trademarks of Sun + Microsystems, Inc. in the U.S. and other countries. + + Federal Acquisitions: Commercial Software - Government Users + Subject to Standard License Terms and Conditions. + + + + + + + + ... + + + The instance documents may indicate the published version of + the schema using the xsi:schemaLocation attribute for J2EE + namespace with the following location: + + http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd + + ]]> + + + + + + + + The following conventions apply to all J2EE + deployment descriptor elements unless indicated otherwise. + + - In elements that specify a pathname to a file within the + same JAR file, relative filenames (i.e., those not + starting with "/") are considered relative to the root of + the JAR file's namespace. Absolute filenames (i.e., those + starting with "/") also specify names in the root of the + JAR file's namespace. In general, relative names are + preferred. The exception is .war files where absolute + names are preferred for consistency with the Servlet API. + + + + + + + + + + + + + + + + The web-app element is the root of the deployment + descriptor for a web application. Note that the sub-elements + of this element can be in the arbitrary order. Because of + that, the multiplicity of the elements of distributable, + session-config, welcome-file-list, jsp-config, login-config, + and locale-encoding-mapping-list was changed from "?" to "*" + in this schema. However, the deployment descriptor instance + file must not contain multiple elements of session-config, + jsp-config, and login-config. When there are multiple elements of + welcome-file-list or locale-encoding-mapping-list, the container + must concatinate the element contents. The multiple occurance + of the element distributable is redundant and the container + treats that case exactly in the same way when there is only + one distributable. + + + + + + + + + The servlet element contains the name of a servlet. + The name must be unique within the web application. + + + + + + + + + + + + + The filter element contains the name of a filter. + The name must be unique within the web application. + + + + + + + + + + + + + The ejb-local-ref-name element contains the name of an EJB + reference. The EJB reference is an entry in the web + application's environment and is relative to the + java:comp/env context. The name must be unique within + the web application. + + It is recommended that name is prefixed with "ejb/". + + + + + + + + + + + + + The ejb-ref-name element contains the name of an EJB + reference. The EJB reference is an entry in the web + application's environment and is relative to the + java:comp/env context. The name must be unique within + the web application. + + It is recommended that name is prefixed with "ejb/". + + + + + + + + + + + + + The resource-env-ref-name element specifies the name of + a resource environment reference; its value is the + environment entry name used in the web application code. + The name is a JNDI name relative to the java:comp/env + context and must be unique within a web application. + + + + + + + + + + + + + The message-destination-ref-name element specifies the name of + a message destination reference; its value is the + environment entry name used in the web application code. + The name is a JNDI name relative to the java:comp/env + context and must be unique within a web application. + + + + + + + + + + + + + The res-ref-name element specifies the name of a + resource manager connection factory reference. The name + is a JNDI name relative to the java:comp/env context. + The name must be unique within a web application. + + + + + + + + + + + + + The env-entry-name element contains the name of a web + application's environment entry. The name is a JNDI + name relative to the java:comp/env context. The name + must be unique within a web application. + + + + + + + + + + + + + + A role-name-key is specified to allow the references + from the security-role-refs. + + + + + + + + + + + + The keyref indicates the references from + security-role-ref to a specified role-name. + + + + + + + + + + + + + + + + The auth-constraintType indicates the user roles that + should be permitted access to this resource + collection. The role-name used here must either correspond + to the role-name of one of the security-role elements + defined for this web application, or be the specially + reserved role-name "*" that is a compact syntax for + indicating all roles in the web application. If both "*" + and rolenames appear, the container interprets this as all + roles. If no roles are defined, no user is allowed access + to the portion of the web application described by the + containing security-constraint. The container matches + role names case sensitively when determining access. + + + + + + + + + + + + + + + + + + + The auth-methodType is used to configure the authentication + mechanism for the web application. As a prerequisite to + gaining access to any web resources which are protected by + an authorization constraint, a user must have authenticated + using the configured mechanism. Legal values are "BASIC", + "DIGEST", "FORM", "CLIENT-CERT", or a vendor-specific + authentication scheme. + + Used in: login-config + + + + + + + + + + + + + + + + The dispatcher has four legal values: FORWARD, REQUEST, INCLUDE, + and ERROR. A value of FORWARD means the Filter will be applied + under RequestDispatcher.forward() calls. A value of REQUEST + means the Filter will be applied under ordinary client calls to + the path or servlet. A value of INCLUDE means the Filter will be + applied under RequestDispatcher.include() calls. A value of + ERROR means the Filter will be applied under the error page + mechanism. The absence of any dispatcher elements in a + filter-mapping indicates a default of applying filters only under + ordinary client calls to the path or servlet. + + + + + + + + + + + + + + + + + + + + + + The encodingType defines IANA character sets. + + + + + + + + + + + + + + + + + The error-code contains an HTTP error code, ex: 404 + + Used in: error-page + + + + + + + + + + + + + + + + + + + + The error-pageType contains a mapping between an error code + or exception type to the path of a resource in the web + application. + + Used in: web-app + + + + + + + + + + + + + + The exception-type contains a fully qualified class + name of a Java exception type. + + + + + + + + + + + + The location element contains the location of the + resource in the web application relative to the root of + the web application. The value of the location must have + a leading `/'. + + + + + + + + + + + + + + + + Declaration of the filter mappings in this web + application is done by using filter-mappingType. + The container uses the filter-mapping + declarations to decide which filters to apply to a request, + and in what order. The container matches the request URI to + a Servlet in the normal way. To determine which filters to + apply it matches filter-mapping declarations either on + servlet-name, or on url-pattern for each filter-mapping + element, depending on which style is used. The order in + which filters are invoked is the order in which + filter-mapping declarations that match a request URI for a + servlet appear in the list of filter-mapping elements.The + filter-name value must be the value of the filter-name + sub-elements of one of the filter declarations in the + deployment descriptor. + + + + + + + + + + + + + + + + + + + + + + + + The logical name of the filter is declare + by using filter-nameType. This name is used to map the + filter. Each filter name is unique within the web + application. + + Used in: filter, filter-mapping + + + + + + + + + + + + + + + + The filterType is used to declare a filter in the web + application. The filter is mapped to either a servlet or a + URL pattern in the filter-mapping element, using the + filter-name value to reference. Filters can access the + initialization parameters declared in the deployment + descriptor at runtime via the FilterConfig interface. + + Used in: web-app + + + + + + + + + + + + + The fully qualified classname of the filter. + + + + + + + + + + The init-param element contains a name/value pair as + an initialization param of a servlet filter + + + + + + + + + + + + + + + + The form-login-configType specifies the login and error + pages that should be used in form based login. If form based + authentication is not used, these elements are ignored. + + Used in: login-config + + + + + + + + + + + + The form-login-page element defines the location in the web + app where the page that can be used for login can be + found. The path begins with a leading / and is interpreted + relative to the root of the WAR. + + + + + + + + + + + The form-error-page element defines the location in + the web app where the error page that is displayed + when login is not successful can be found. + The path begins with a leading / and is interpreted + relative to the root of the WAR. + + + + + + + + + + + + + + + + + The http-method contains an HTTP method recognized by the + web-app, for example GET, POST, ... + + + + + + + + + + + + + + + + + + + + + + + + + The locale-encoding-mapping-list contains one or more + locale-encoding-mapping(s). + + + + + + + + + + + + + + + + + + The locale-encoding-mapping contains locale name and + encoding name. The locale name must be either "Language-code", + such as "ja", defined by ISO-639 or "Language-code_Country-code", + such as "ja_JP". "Country code" is defined by ISO-3166. + + + + + + + + + + + + + + + + + + + The localeType defines valid locale defined by ISO-639-1 + and ISO-3166. + + + + + + + + + + + + + + + + + The login-configType is used to configure the authentication + method that should be used, the realm name that should be + used for this application, and the attributes that are + needed by the form login mechanism. + + Used in: web-app + + + + + + + + + + + + The realm name element specifies the realm name to + use in HTTP Basic authorization. + + + + + + + + + + + + + + + + + + The mime-mappingType defines a mapping between an extension + and a mime type. + + Used in: web-app + + + + + + + + + The extension element contains a string describing an + extension. example: "txt" + + + + + + + + + + + + + + + + + The mime-typeType is used to indicate a defined mime type. + + Example: + "text/plain" + + Used in: mime-mapping + + + + + + + + + + + + + + + + + + + This type defines a string which contains at least one + character. + + + + + + + + + + + + + + + + + The security-constraintType is used to associate + security constraints with one or more web resource + collections + + Used in: web-app + + + + + + + + + + + + + + + + + + + + The servlet-mappingType defines a mapping between a + servlet and a url pattern. + + Used in: web-app + + + + + + + + + + + + + + + + + + + + The servlet-name element contains the canonical name of the + servlet. Each servlet name is unique within the web + application. + + + + + + + + + + + + + + + + The servletType is used to declare a servlet. + It contains the declarative data of a + servlet. If a jsp-file is specified and the load-on-startup + element is present, then the JSP should be precompiled and + loaded. + + Used in: web-app + + + + + + + + + + + + + + The servlet-class element contains the fully + qualified class name of the servlet. + + + + + + + + + + + + + + + + The load-on-startup element indicates that this + servlet should be loaded (instantiated and have + its init() called) on the startup of the web + application. The optional contents of these + element must be an integer indicating the order in + which the servlet should be loaded. If the value + is a negative integer, or the element is not + present, the container is free to load the servlet + whenever it chooses. If the value is a positive + integer or 0, the container must load and + initialize the servlet as the application is + deployed. The container must guarantee that + servlets marked with lower integers are loaded + before servlets marked with higher integers. The + container may choose the order of loading of + servlets with the same load-on-start-up value. + + + + + + + + + + + + + + + + + The session-configType defines the session parameters + for this web application. + + Used in: web-app + + + + + + + + + + + The session-timeout element defines the default + session timeout interval for all sessions created + in this web application. The specified timeout + must be expressed in a whole number of minutes. + If the timeout is 0 or less, the container ensures + the default behaviour of sessions is never to time + out. If this element is not specified, the container + must set its default timeout period. + + + + + + + + + + + + + + + + The transport-guaranteeType specifies that the communication + between client and server should be NONE, INTEGRAL, or + CONFIDENTIAL. NONE means that the application does not + require any transport guarantees. A value of INTEGRAL means + that the application requires that the data sent between the + client and server be sent in such a way that it can't be + changed in transit. CONFIDENTIAL means that the application + requires that the data be transmitted in a fashion that + prevents other entities from observing the contents of the + transmission. In most cases, the presence of the INTEGRAL or + CONFIDENTIAL flag will indicate that the use of SSL is + required. + + Used in: user-data-constraint + + + + + + + + + + + + + + + + + + + + The user-data-constraintType is used to indicate how + data communicated between the client and container should be + protected. + + Used in: security-constraint + + + + + + + + + + + + + + + + + + + + The elements that use this type designate a path starting + with a "/" and interpreted relative to the root of a WAR + file. + + + + + + + + + + + + + + + + + + This type contains the recognized versions of + web-application supported. It is used to designate the + version of the web application. + + + + + + + + + + + + + + + + + + + + + + + The context-param element contains the declaration + of a web application's servlet context + initialization parameters. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The web-resource-collectionType is used to identify a subset + of the resources and HTTP methods on those resources within + a web application to which a security constraint applies. If + no HTTP methods are specified, then the security constraint + applies to all HTTP methods. + + Used in: security-constraint + + + + + + + + + + The web-resource-name contains the name of this web + resource collection. + + + + + + + + + + + + + + + + + + + The welcome-file-list contains an ordered list of welcome + files elements. + + Used in: web-app + + + + + + + + + + + The welcome-file element contains file name to use + as a default welcome file, such as index.html + + + + + + + + + + diff --git a/exo.jcr.component.webdav/src/main/resources/dtd/xhtml-lat1.ent b/exo.jcr.component.webdav/src/main/resources/dtd/xhtml-lat1.ent new file mode 100644 index 0000000000..ffee223eb1 --- /dev/null +++ b/exo.jcr.component.webdav/src/main/resources/dtd/xhtml-lat1.ent @@ -0,0 +1,196 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/exo.jcr.component.webdav/src/main/resources/dtd/xhtml-special.ent b/exo.jcr.component.webdav/src/main/resources/dtd/xhtml-special.ent new file mode 100644 index 0000000000..ca358b2fec --- /dev/null +++ b/exo.jcr.component.webdav/src/main/resources/dtd/xhtml-special.ent @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/exo.jcr.component.webdav/src/main/resources/dtd/xhtml-symbol.ent b/exo.jcr.component.webdav/src/main/resources/dtd/xhtml-symbol.ent new file mode 100644 index 0000000000..63c2abfa6f --- /dev/null +++ b/exo.jcr.component.webdav/src/main/resources/dtd/xhtml-symbol.ent @@ -0,0 +1,237 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/exo.jcr.component.webdav/src/main/resources/dtd/xhtml1-frameset.dtd b/exo.jcr.component.webdav/src/main/resources/dtd/xhtml1-frameset.dtd new file mode 100644 index 0000000000..b22e50705a --- /dev/null +++ b/exo.jcr.component.webdav/src/main/resources/dtd/xhtml1-frameset.dtd @@ -0,0 +1,1235 @@ + + + + + +%HTMLlat1; + + +%HTMLsymbol; + + +%HTMLspecial; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/exo.jcr.component.webdav/src/main/resources/dtd/xhtml1-strict.dtd b/exo.jcr.component.webdav/src/main/resources/dtd/xhtml1-strict.dtd new file mode 100644 index 0000000000..9f1095d312 --- /dev/null +++ b/exo.jcr.component.webdav/src/main/resources/dtd/xhtml1-strict.dtd @@ -0,0 +1,978 @@ + + + + + +%HTMLlat1; + + +%HTMLsymbol; + + +%HTMLspecial; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/exo.jcr.component.webdav/src/main/resources/dtd/xhtml1-transitional.dtd b/exo.jcr.component.webdav/src/main/resources/dtd/xhtml1-transitional.dtd new file mode 100644 index 0000000000..a182723bee --- /dev/null +++ b/exo.jcr.component.webdav/src/main/resources/dtd/xhtml1-transitional.dtd @@ -0,0 +1,1201 @@ + + + + + +%HTMLlat1; + + +%HTMLsymbol; + + +%HTMLspecial; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/exo.jcr.component.webdav/src/main/resources/dtd/xml.xsd b/exo.jcr.component.webdav/src/main/resources/dtd/xml.xsd new file mode 100644 index 0000000000..f82cdabd7b --- /dev/null +++ b/exo.jcr.component.webdav/src/main/resources/dtd/xml.xsd @@ -0,0 +1,120 @@ + + + + + + + See http://www.w3.org/XML/1998/namespace.html and + http://www.w3.org/TR/REC-xml for information about this namespace. + + This schema document describes the XML namespace, in a form + suitable for import by other schema documents. + + Note that local names in this namespace are intended to be defined + only by the World Wide Web Consortium or its subgroups. The + following names are currently defined in this namespace and should + not be used with conflicting semantics by any Working Group, + specification, or document instance: + + base (as an attribute name): denotes an attribute whose value + provides a URI to be used as the base for interpreting any + relative URIs in the scope of the element on which it + appears; its value is inherited. This name is reserved + by virtue of its definition in the XML Base specification. + + lang (as an attribute name): denotes an attribute whose value + is a language code for the natural language of the content of + any element; its value is inherited. This name is reserved + by virtue of its definition in the XML specification. + + space (as an attribute name): denotes an attribute whose + value is a keyword indicating what whitespace processing + discipline is intended for the content of the element; its + value is inherited. This name is reserved by virtue of its + definition in the XML specification. + + Father (in any context at all): denotes Jon Bosak, the chair of + the original XML Working Group. This name is reserved by + the following decision of the W3C XML Plenary and + XML Coordination groups: + + In appreciation for his vision, leadership and dedication + the W3C XML Plenary on this 10th day of February, 2000 + reserves for Jon Bosak in perpetuity the XML name + xml:Father + + + + + This schema defines attributes and an attribute group + suitable for use by + schemas wishing to allow xml:base, xml:lang or xml:space attributes + on elements they define. + + To enable this, such a schema must import this schema + for the XML namespace, e.g. as follows: + <schema . . .> + . . . + <import namespace="http://www.w3.org/XML/1998/namespace" + schemaLocation="http://www.w3.org/2001/03/xml.xsd"/> + + Subsequently, qualified reference to any of the attributes + or the group defined below will have the desired effect, e.g. + + <type . . .> + . . . + <attributeGroup ref="xml:specialAttrs"/> + + will define a type which will schema-validate an instance + element with any of those attributes + + + + + In keeping with the XML Schema WG's standard versioning + policy, this schema document will persist at + http://www.w3.org/2001/03/xml.xsd. + At the date of issue it can also be found at + http://www.w3.org/2001/xml.xsd. + The schema document at that URI may however change in the future, + in order to remain compatible with the latest version of XML Schema + itself. In other words, if the XML Schema namespace changes, the version + of this document at + http://www.w3.org/2001/xml.xsd will change + accordingly; the version at + http://www.w3.org/2001/03/xml.xsd will not change. + + + + + + In due course, we should install the relevant ISO 2- and 3-letter + codes as the enumerated possible values . . . + + + + + + + + + + + + + + + + + See http://www.w3.org/TR/xmlbase/ for + information about this attribute. + + + + + + + + + + \ No newline at end of file diff --git a/exo.jcr.component.webdav/src/main/resources/xslt/html-url-rewite.xsl b/exo.jcr.component.webdav/src/main/resources/xslt/html-url-rewite.xsl new file mode 100644 index 0000000000..09da7429f5 --- /dev/null +++ b/exo.jcr.component.webdav/src/main/resources/xslt/html-url-rewite.xsl @@ -0,0 +1,156 @@ + + + + + + + + + + + url + + + + + + + + + + + + + + + + Parameter list: + portalURI=[ + + ] portletURI=[ + + ] param-name=[ + + ] portalContextPath =[ + + ] portalQueryString =[ + + ] paramNamespace =[ + + ] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + *begin**********Auto added fields*********[new url= + + + + *end**********Auto added fields********* + + + + + + + + + + + + + + + hidden + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + / + + + + + ? + + + & + + + + + = + + + + + + diff --git a/exo.jcr.component.webdav/src/test/resources/conf/standalone/test-configuration.xml b/exo.jcr.component.webdav/src/test/resources/conf/standalone/test-configuration.xml index ea69a64349..5c7d244414 100644 --- a/exo.jcr.component.webdav/src/test/resources/conf/standalone/test-configuration.xml +++ b/exo.jcr.component.webdav/src/test/resources/conf/standalone/test-configuration.xml @@ -37,6 +37,224 @@ + + org.exoplatform.services.naming.InitialContextInitializer + org.exoplatform.services.naming.InitialContextInitializer + + + bind.datasource + addPlugin + org.exoplatform.services.naming.BindReferencePlugin + + + bind-name + jdbcjcr + + + class-name + javax.sql.DataSource + + + factory + org.apache.commons.dbcp.BasicDataSourceFactory + + + ref-addresses + ref-addresses + + + + + + + + + + + default-properties + Default initial context properties + + + + + + + org.exoplatform.services.xml.resolving.impl.XMLResolvingServiceImpl + + + add.resolving.table + addPlugin + org.exoplatform.services.xml.resolving.impl.AddXMLResolvingContextPlugin + + + dtd1 + + + + + + dtd2 + + + + + + + + + + + org.exoplatform.services.xml.transform.impl.trax.TRAXTransformerServiceImpl + + + + org.exoplatform.services.xml.transform.impl.trax.TRAXTemplatesServiceImpl + + + add.xslschema + addPlugin + org.exoplatform.services.xml.transform.impl.trax.TRAXTemplatesLoaderPlugin + + + xsl-source-urls + + + + + + + + org.exoplatform.services.xml.transform.impl.EncodingMapImpl + + + + org.exoplatform.services.idgenerator.IDGeneratorService + org.exoplatform.services.idgenerator.impl.IDGeneratorServiceImpl + + + + org.exoplatform.services.jdbc.DataSourceProvider + org.exoplatform.services.jdbc.impl.DataSourceProviderImpl + + + + org.exoplatform.services.jcr.impl.RepositoryCreationSynchronizer + + + disabled + false + + + + + + + org.exoplatform.services.document.DocumentReaderService + org.exoplatform.services.document.impl.tika.TikaDocumentReaderServiceImpl + + + + pdf.document.reader + addDocumentReader + org.exoplatform.services.document.impl.PDFDocumentReader + to read the pdf inputstream + + + + document.readerMSWord + addDocumentReader + org.exoplatform.services.document.impl.MSWordDocumentReader + to read the ms word inputstream + + + + document.readerMSXWord + addDocumentReader + org.exoplatform.services.document.impl.MSXWordDocumentReader + to read the ms word inputstream + + + + document.readerMSExcel + addDocumentReader + org.exoplatform.services.document.impl.MSExcelDocumentReader + to read the ms excel inputstream + + + + document.readerMSXExcel + addDocumentReader + org.exoplatform.services.document.impl.MSXExcelDocumentReader + to read the ms excel inputstream + + + + document.readerMSOutlook + addDocumentReader + org.exoplatform.services.document.impl.MSOutlookDocumentReader + to read the ms outlook inputstream + + + + PPTdocument.reader + addDocumentReader + org.exoplatform.services.document.impl.PPTDocumentReader + to read the ms ppt inputstream + + + + MSXPPTdocument.reader + addDocumentReader + org.exoplatform.services.document.impl.MSXPPTDocumentReader + to read the ms pptx inputstream + + + + document.readerHTML + addDocumentReader + org.exoplatform.services.document.impl.HTMLDocumentReader + to read the html inputstream + + + + document.readerXML + addDocumentReader + org.exoplatform.services.document.impl.XMLDocumentReader + to read the xml inputstream + + + + TPdocument.reader + addDocumentReader + org.exoplatform.services.document.impl.TextPlainDocumentReader + to read the plain text inputstream + + + + + + + document.readerOO + addDocumentReader + org.exoplatform.services.document.impl.OpenOfficeDocumentReader + to read the OO inputstream + + + + + + + tika-configuration + jar:/conf/portal/tika-config.xml + + + + org.exoplatform.services.jcr.RepositoryService org.exoplatform.services.jcr.impl.RepositoryServiceImpl diff --git a/exo.jcr.component.webdav/src/test/resources/dtd-not-found.xml b/exo.jcr.component.webdav/src/test/resources/dtd-not-found.xml new file mode 100644 index 0000000000..79b3b23f3d --- /dev/null +++ b/exo.jcr.component.webdav/src/test/resources/dtd-not-found.xml @@ -0,0 +1,27 @@ + + + + + + diff --git a/exo.jcr.component.webdav/src/test/resources/html-url-rewite.xsl b/exo.jcr.component.webdav/src/test/resources/html-url-rewite.xsl new file mode 100644 index 0000000000..09da7429f5 --- /dev/null +++ b/exo.jcr.component.webdav/src/test/resources/html-url-rewite.xsl @@ -0,0 +1,156 @@ + + + + + + + + + + + url + + + + + + + + + + + + + + + + Parameter list: + portalURI=[ + + ] portletURI=[ + + ] param-name=[ + + ] portalContextPath =[ + + ] portalQueryString =[ + + ] paramNamespace =[ + + ] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + *begin**********Auto added fields*********[new url= + + + + *end**********Auto added fields********* + + + + + + + + + + + + + + + hidden + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + / + + + + + ? + + + & + + + + + = + + + + + + diff --git a/exo.jcr.component.webdav/src/test/resources/rss-in.html b/exo.jcr.component.webdav/src/test/resources/rss-in.html new file mode 100644 index 0000000000..6f0730683d --- /dev/null +++ b/exo.jcr.component.webdav/src/test/resources/rss-in.html @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+Current News from Slashdot +
+
25,000-Ton Amphibious Spam Relay111timothy2003-12-17 19:53:00
Gloolabs Readies A Java-Based WiFi Audio Device193timothy2003-12-17 19:04:00
Microsoft's New Core OS Team Learning from Linux201CmdrTaco2003-12-17 18:16:00
3D Modelling From a Sketch134CmdrTaco2003-12-17 17:30:00
Server CE Database Development with .NET156timothy2003-12-17 16:30:00
City Of Austin Migrating To OpenOffice.org185timothy2003-12-17 15:32:00
Blockbuster Chief: End DVD Region Codes187timothy2003-12-17 14:38:00
55 Operating Systems On A PowerBook180timothy2003-12-17 13:43:00
(At Least) 100 Years Of Powered Human Flight126timothy2003-12-17 12:52:00
Israeli Gov't Begins Testing Mandrake Linux147timothy2003-12-17 09:20:00
+ + diff --git a/exo.jcr.component.webdav/src/test/resources/rss-in.xhtml b/exo.jcr.component.webdav/src/test/resources/rss-in.xhtml new file mode 100644 index 0000000000..b750d3012e --- /dev/null +++ b/exo.jcr.component.webdav/src/test/resources/rss-in.xhtml @@ -0,0 +1,127 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
Current News +from Slashdot
+
25,000-Ton +Amphibious Spam Relay111timothy2003-12-17 19:53:00
Gloolabs Readies A +Java-Based WiFi Audio Device193timothy2003-12-17 19:04:00
Microsoft's New +Core OS Team Learning from Linux201CmdrTaco2003-12-17 18:16:00
3D Modelling From a +Sketch134CmdrTaco2003-12-17 17:30:00
Server CE Database +Development with .NET156timothy2003-12-17 16:30:00
City Of Austin +Migrating To OpenOffice.org185timothy2003-12-17 15:32:00
Blockbuster Chief: +End DVD Region Codes187timothy2003-12-17 14:38:00
55 Operating +Systems On A PowerBook180timothy2003-12-17 13:43:00
(At Least) 100 +Years Of Powered Human Flight126timothy2003-12-17 12:52:00
Israeli Gov't +Begins Testing Mandrake Linux147timothy2003-12-17 09:20:00
+ + + diff --git a/exo.jcr.component.webdav/src/test/resources/test.policy b/exo.jcr.component.webdav/src/test/resources/test.policy new file mode 100644 index 0000000000..0497820a2d --- /dev/null +++ b/exo.jcr.component.webdav/src/test/resources/test.policy @@ -0,0 +1,11 @@ +grant codeBase "@MAVEN_REPO@-"{ + permission java.security.AllPermission; +}; + +grant codeBase "@MAIN_CLASSES@-"{ + permission java.security.AllPermission; +}; + +grant codeBase "@TEST_CLASSES@-"{ + permission java.lang.RuntimePermission "accessClassInPackage.com.ibm.xtq.xml.xdm.ref"; +}; diff --git a/exo.jcr.component.webdav/src/test/resources/web-app_2_3.dtd b/exo.jcr.component.webdav/src/test/resources/web-app_2_3.dtd new file mode 100644 index 0000000000..5e3ab01c0f --- /dev/null +++ b/exo.jcr.component.webdav/src/test/resources/web-app_2_3.dtd @@ -0,0 +1,1063 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/exo.jcr.component.webdav/src/test/resources/web.xml b/exo.jcr.component.webdav/src/test/resources/web.xml new file mode 100644 index 0000000000..074e553f33 --- /dev/null +++ b/exo.jcr.component.webdav/src/test/resources/web.xml @@ -0,0 +1,43 @@ + + + + + + + + HelloWorld + + This application is a portlet. It can not be used outside a portal. + This web.xml file is mandatory in each .par archive file. + + + + index.html + + + + portlet + /WEB-INF/tlds/portlet.tld + + diff --git a/jcr-packaging/src/main/assemblies/jcr-addon-package.xml b/jcr-packaging/src/main/assemblies/jcr-addon-package.xml index b304f451ec..70df0458ed 100644 --- a/jcr-packaging/src/main/assemblies/jcr-addon-package.xml +++ b/jcr-packaging/src/main/assemblies/jcr-addon-package.xml @@ -114,16 +114,13 @@ *:common-common:jar *:common-logging:jar *:commons-beanutils:jar - *:commons-chain:jar *:commons-codec:jar *:commons-collections:jar *:commons-compress:* *:commons-dbcp:jar - *:commons-digester:jar *:commons-fileupload:jar *:commons-io:jar *:commons-lang3:jar - *:commons-pool:jar *:dom4j:jar *:fontbox:jar *:groovy-all:jar @@ -131,8 +128,6 @@ *:hibernate-core:jar *:hibernate-jpa-2.0-api:jar *:httpclient:jar - *:infinispan-commons:jar - *:infinispan-core:jar *:isoparser:jar *:guava:jar *:jakarta-regexp:jar @@ -142,10 +137,7 @@ *:jakarta.xml.bind-api:jar *:jboss-logging:jar *:jboss-logging-annotations:jar - *:jboss-marshalling-osgi:jar - *:jbossjta:jar *:jcl-over-slf4j:jar - *:jgroups:jar *:jhighlight:jar *:jibx-run:jar *:json-simple:jar