Return-Path: X-Original-To: apmail-zest-commits-archive@minotaur.apache.org Delivered-To: apmail-zest-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 453A4186C0 for ; Thu, 30 Jul 2015 19:48:02 +0000 (UTC) Received: (qmail 61455 invoked by uid 500); 30 Jul 2015 19:48:02 -0000 Delivered-To: apmail-zest-commits-archive@zest.apache.org Received: (qmail 61432 invoked by uid 500); 30 Jul 2015 19:48:02 -0000 Mailing-List: contact commits-help@zest.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@zest.apache.org Delivered-To: mailing list commits@zest.apache.org Received: (qmail 60414 invoked by uid 99); 30 Jul 2015 19:48:01 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 30 Jul 2015 19:48:01 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 1FBE3E714C; Thu, 30 Jul 2015 19:48:01 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: niclas@apache.org To: commits@zest.apache.org Date: Thu, 30 Jul 2015 19:48:49 -0000 Message-Id: In-Reply-To: <4cbd2683fa884aa6bf1c8b2865185ebf@git.apache.org> References: <4cbd2683fa884aa6bf1c8b2865185ebf@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [50/80] [partial] zest-java git commit: First round of changes to move to org.apache.zest namespace. http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/buildSrc/src/main/groovy/org/apache/zest/gradle/plugin/Documentation.groovy ---------------------------------------------------------------------- diff --git a/buildSrc/src/main/groovy/org/apache/zest/gradle/plugin/Documentation.groovy b/buildSrc/src/main/groovy/org/apache/zest/gradle/plugin/Documentation.groovy new file mode 100644 index 0000000..3c06602 --- /dev/null +++ b/buildSrc/src/main/groovy/org/apache/zest/gradle/plugin/Documentation.groovy @@ -0,0 +1,240 @@ +/* + * Copyright (c) 2011, Niclas Hedhman. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + */ +package org.apache.zest.gradle.plugin; + + +import org.gradle.api.DefaultTask +import org.gradle.api.tasks.TaskAction +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.InputDirectory +import org.gradle.api.tasks.InputFile +import org.gradle.api.tasks.InputFiles +import org.gradle.api.tasks.OutputDirectory + +// TODO: try to use dependencies for FOP and execute within the same JVM. +// TODO: move the bulk of resources into this plugin, instead of sitting in the project. +class Documentation extends DefaultTask +{ + @Input def String docName + @Input def String docType + void setDocName( String docName ) { this.docName = docName } + void setDocType( String docType ) { this.docType = docType } + + @InputDirectory def File getCommonResourcesDir() { project.file( 'src/resources' ) } + @InputDirectory def File getConfigDir() { project.file( 'src/conf' ) } + @InputDirectory def File getDocsDir() { project.file( 'src/docs') } + @InputDirectory def File getSrcMainDir() { project.file( 'src/main') } + @InputDirectory def File getXslDir() { project.file( 'src/xsl') } + @InputDirectory def File getBuildSrcDir() { project.rootProject.file( 'buildSrc/src' ) } + + @InputFiles def getSubProjectsDocsDirs() { project.rootProject.subprojects.collect { p -> p.file( 'src/docs' ) } } + @InputFiles def getSubProjectsTestDirs() { project.rootProject.subprojects.collect { p -> p.file( 'src/test' ) } } + + @OutputDirectory def File getOutputDir() { project.file( "${project.buildDir}/docs/${docName}/" ) } + + def File getTempAsciidocDir() { project.file( "${project.buildDir}/tmp-asciidoc" ) } + def File getTempDir() { project.file( "${project.buildDir}/tmp/docs/${docName}") } + + @TaskAction + def void generate() + { + installAsciidocFilters() + + [ outputDir, tempAsciidocDir, tempDir ]*.deleteDir() + [ outputDir, tempAsciidocDir, tempDir ]*.mkdirs() + + copySubProjectsDocsResources() + generateAsciidocAccordingToReleaseSpecification() + generateXDoc() + generateChunkedHtml() + // generateSingleHtml() + // generatePdf() + } + + def void installAsciidocFilters() + { + def userHome = new File( System.getProperty( 'user.home' ) ) + def snippetDir = new File( userHome, '.asciidoc/filters/snippet' ).absoluteFile + if( !snippetDir.exists() ) + { + println "Installing [snippet] into $snippetDir" + snippetDir.mkdirs() + project.copy { + from "${project.rootDir}/buildSrc/src/bin" + into snippetDir + include 'snippet.*' + } + ant.chmod( dir: snippetDir, perm: '755', includes: 'snippet.py' ) + } + + def devstatusDir = new File( userHome, '.asciidoc/filters/devstatus' ).absoluteFile + if( !devstatusDir.exists() ) + { + println "Installing [devstatus] into $devstatusDir" + snippetDir.mkdirs() + project.copy { + from "${project.rootDir}/buildSrc/src/bin" + into devstatusDir + include 'devstatus.*' + } + ant.chmod( dir: devstatusDir, perm: '755', includes: 'devstatus.py' ) + } + } + + def void copySubProjectsDocsResources() + { + project.rootProject.subprojects.each { p -> + p.copy { + from p.file( 'src/docs/resources' ) + into outputDir + include '**' + } + } + } + + def void generateAsciidocAccordingToReleaseSpecification() + { + project.copy { + from docsDir + into tempAsciidocDir + include '**' + } + if( project.version != '0' && !project.version.contains( 'SNAPSHOT' ) ) { + def licenseFile = new File( tempAsciidocDir, 'userguide/libraries.txt' ) + def extensionsFile = new File( tempAsciidocDir, 'userguide/extensions.txt' ) + def toolsFile = new File( tempAsciidocDir, 'userguide/tools.txt' ) + [ licenseFile, extensionsFile, toolsFile ].each { asciidocFile -> + def filteredFileContent = '' + asciidocFile.readLines().each { line -> + if( line.startsWith( 'include::' ) ) { + def approved = false + project.rootProject.releaseApprovedProjects.collect{it.projectDir}.each { approvedProjectDir -> + if( line.contains( "${approvedProjectDir.parentFile.name}/${approvedProjectDir.name}" ) ) { + approved = true + } + } + if( approved ) { + filteredFileContent += "$line\n" + } + } else { + filteredFileContent += "$line\n" + } + } + asciidocFile.text = filteredFileContent + } + } + } + + def void generateXDoc() + { + project.exec { + executable = 'asciidoc' + workingDir = '..' + def commonResourcesPath = relativePath( project.rootDir, commonResourcesDir ) + def asciidocConfigPath = relativePath( project.rootDir, new File( configDir, 'asciidoc.conf' ) ) + def docbookConfigPath = relativePath( project.rootDir, new File( configDir, 'docbook45.conf' ) ) + def linkimagesConfigPath = relativePath( project.rootDir, new File( configDir, 'linkedimages.conf' ) ) + def xdocOutputPath = relativePath( project.rootDir, new File( tempDir, 'xdoc-temp.xml' ) ) + def asciidocIndexPath = relativePath( project.rootDir, new File( tempAsciidocDir, "$docName/index.txt" ) ) + args = [ + '--attribute', 'revnumber=' + project.version, + '--attribute', 'level1=' + (docType.equals('article') ? 1 : 0), + '--attribute', 'level2=' + (docType.equals('article') ? 2 : 1), + '--attribute', 'level3=' + (docType.equals('article') ? 3 : 2), + '--attribute', 'level4=' + (docType.equals('article') ? 4 : 3), + '--attribute', 'importdir=' + commonResourcesPath, + '--backend', 'docbook', + '--attribute', 'docinfo1', + '--doctype', docType, + '--conf-file=' + asciidocConfigPath, + '--conf-file=' + docbookConfigPath, + '--conf-file=' + linkimagesConfigPath, + '--out-file', xdocOutputPath, + asciidocIndexPath + ] + } + } + + def void generateChunkedHtml() + { + project.copy { + from commonResourcesDir + into outputDir + include '**' + } + project.copy { + from "$docsDir/$docName/resources" + into outputDir + include '**' + } + + project.exec { + def xsltFile = "$docsDir/$docName/xsl/chunked.xsl" + def outputPath = relativePath( project.projectDir, outputDir ) + '/' + executable = 'xsltproc' + args = [ + '--nonet', + '--noout', + '--output', outputPath, + xsltFile, + "$tempDir/xdoc-temp.xml" + ] + } + } + + def void generateSingleHtml() + { + project.exec { + // XML_CATALOG_FILES= + String xsltFile = "$xslDir/xhtml.xsl" + executable = 'xsltproc' + args = [ + '--nonet', + '--noout', + '--output', "$outputDir/${docName}.html", + xsltFile, + "$tempDir/xdoc-temp.xml" + ] + } + } + + def void generatePdf() + { + // $ xsltproc --nonet ../docbook-xsl/fo.xsl article.xml > article.fo + // $ fop article.fo article.pdf + project.exec { + String xsltFile = "$xslDir/fo.xsl" + executable = 'xsltproc' + args = [ + '--nonet', + '--output', "$tempDir/${docName}.fo", + xsltFile, + "$tempDir/xdoc-temp.xml" + ] + } + project.exec { + executable = 'fop' + args = [ + "$tempDir/${docName}.fo", + "$outputDir/${docName}.pdf" + ] + } + } + + def String relativePath( File root, File target ) + { + new File( root.toURI().relativize( target.toURI() ).toString() ).path + } +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/buildSrc/src/main/groovy/org/apache/zest/gradle/plugin/ModuleReleaseSpecification.groovy ---------------------------------------------------------------------- diff --git a/buildSrc/src/main/groovy/org/apache/zest/gradle/plugin/ModuleReleaseSpecification.groovy b/buildSrc/src/main/groovy/org/apache/zest/gradle/plugin/ModuleReleaseSpecification.groovy new file mode 100644 index 0000000..2d4e34e --- /dev/null +++ b/buildSrc/src/main/groovy/org/apache/zest/gradle/plugin/ModuleReleaseSpecification.groovy @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2011, Niclas Hedhman. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + */ +package org.apache.zest.gradle.plugin; + +import org.gradle.api.Project + +class ModuleReleaseSpecification +{ + def boolean satisfiedBy( Project project ) + { + def devStatusFile = new File( project.projectDir, "dev-status.xml" ) + if( !devStatusFile.exists() ) + { + return false + } + def module = new XmlSlurper().parse( devStatusFile ) + def codebase = module.status.codebase.text() + def docs = module.status.documentation.text() + def tests = module.status.unittests.text() + def satisfied = ( codebase == 'none' && docs == 'complete' && tests != 'complete' ) + satisfied |= ( codebase == 'early' && ( docs == 'complete' || docs == 'good') && (tests == 'complete' || tests == 'good' ) ) + satisfied |= ( codebase == 'beta' && (docs == 'complete' || docs == 'good' || docs == 'brief') && (tests == 'complete' || tests == 'good' || tests == 'some') ) + satisfied |= ( codebase == 'stable' ) + satisfied |= ( codebase == 'mature' ) + println "$project.name($satisfied) -> $codebase, $docs, $tests" + return satisfied + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/buildSrc/src/main/groovy/org/qi4j/gradle/plugin/Documentation.groovy ---------------------------------------------------------------------- diff --git a/buildSrc/src/main/groovy/org/qi4j/gradle/plugin/Documentation.groovy b/buildSrc/src/main/groovy/org/qi4j/gradle/plugin/Documentation.groovy deleted file mode 100644 index ad8ca04..0000000 --- a/buildSrc/src/main/groovy/org/qi4j/gradle/plugin/Documentation.groovy +++ /dev/null @@ -1,240 +0,0 @@ -/* - * Copyright (c) 2011, Niclas Hedhman. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, - * either express or implied. - * See the License for the specific language governing permissions - * and limitations under the License. - */ -package org.qi4j.gradle.plugin; - - -import org.gradle.api.DefaultTask -import org.gradle.api.tasks.TaskAction -import org.gradle.api.tasks.Input -import org.gradle.api.tasks.InputDirectory -import org.gradle.api.tasks.InputFile -import org.gradle.api.tasks.InputFiles -import org.gradle.api.tasks.OutputDirectory - -// TODO: try to use dependencies for FOP and execute within the same JVM. -// TODO: move the bulk of resources into this plugin, instead of sitting in the project. -class Documentation extends DefaultTask -{ - @Input def String docName - @Input def String docType - void setDocName( String docName ) { this.docName = docName } - void setDocType( String docType ) { this.docType = docType } - - @InputDirectory def File getCommonResourcesDir() { project.file( 'src/resources' ) } - @InputDirectory def File getConfigDir() { project.file( 'src/conf' ) } - @InputDirectory def File getDocsDir() { project.file( 'src/docs') } - @InputDirectory def File getSrcMainDir() { project.file( 'src/main') } - @InputDirectory def File getXslDir() { project.file( 'src/xsl') } - @InputDirectory def File getBuildSrcDir() { project.rootProject.file( 'buildSrc/src' ) } - - @InputFiles def getSubProjectsDocsDirs() { project.rootProject.subprojects.collect { p -> p.file( 'src/docs' ) } } - @InputFiles def getSubProjectsTestDirs() { project.rootProject.subprojects.collect { p -> p.file( 'src/test' ) } } - - @OutputDirectory def File getOutputDir() { project.file( "${project.buildDir}/docs/${docName}/" ) } - - def File getTempAsciidocDir() { project.file( "${project.buildDir}/tmp-asciidoc" ) } - def File getTempDir() { project.file( "${project.buildDir}/tmp/docs/${docName}") } - - @TaskAction - def void generate() - { - installAsciidocFilters() - - [ outputDir, tempAsciidocDir, tempDir ]*.deleteDir() - [ outputDir, tempAsciidocDir, tempDir ]*.mkdirs() - - copySubProjectsDocsResources() - generateAsciidocAccordingToReleaseSpecification() - generateXDoc() - generateChunkedHtml() - // generateSingleHtml() - // generatePdf() - } - - def void installAsciidocFilters() - { - def userHome = new File( System.getProperty( 'user.home' ) ) - def snippetDir = new File( userHome, '.asciidoc/filters/snippet' ).absoluteFile - if( !snippetDir.exists() ) - { - println "Installing [snippet] into $snippetDir" - snippetDir.mkdirs() - project.copy { - from "${project.rootDir}/buildSrc/src/bin" - into snippetDir - include 'snippet.*' - } - ant.chmod( dir: snippetDir, perm: '755', includes: 'snippet.py' ) - } - - def devstatusDir = new File( userHome, '.asciidoc/filters/devstatus' ).absoluteFile - if( !devstatusDir.exists() ) - { - println "Installing [devstatus] into $devstatusDir" - snippetDir.mkdirs() - project.copy { - from "${project.rootDir}/buildSrc/src/bin" - into devstatusDir - include 'devstatus.*' - } - ant.chmod( dir: devstatusDir, perm: '755', includes: 'devstatus.py' ) - } - } - - def void copySubProjectsDocsResources() - { - project.rootProject.subprojects.each { p -> - p.copy { - from p.file( 'src/docs/resources' ) - into outputDir - include '**' - } - } - } - - def void generateAsciidocAccordingToReleaseSpecification() - { - project.copy { - from docsDir - into tempAsciidocDir - include '**' - } - if( project.version != '0' && !project.version.contains( 'SNAPSHOT' ) ) { - def licenseFile = new File( tempAsciidocDir, 'userguide/libraries.txt' ) - def extensionsFile = new File( tempAsciidocDir, 'userguide/extensions.txt' ) - def toolsFile = new File( tempAsciidocDir, 'userguide/tools.txt' ) - [ licenseFile, extensionsFile, toolsFile ].each { asciidocFile -> - def filteredFileContent = '' - asciidocFile.readLines().each { line -> - if( line.startsWith( 'include::' ) ) { - def approved = false - project.rootProject.releaseApprovedProjects.collect{it.projectDir}.each { approvedProjectDir -> - if( line.contains( "${approvedProjectDir.parentFile.name}/${approvedProjectDir.name}" ) ) { - approved = true - } - } - if( approved ) { - filteredFileContent += "$line\n" - } - } else { - filteredFileContent += "$line\n" - } - } - asciidocFile.text = filteredFileContent - } - } - } - - def void generateXDoc() - { - project.exec { - executable = 'asciidoc' - workingDir = '..' - def commonResourcesPath = relativePath( project.rootDir, commonResourcesDir ) - def asciidocConfigPath = relativePath( project.rootDir, new File( configDir, 'asciidoc.conf' ) ) - def docbookConfigPath = relativePath( project.rootDir, new File( configDir, 'docbook45.conf' ) ) - def linkimagesConfigPath = relativePath( project.rootDir, new File( configDir, 'linkedimages.conf' ) ) - def xdocOutputPath = relativePath( project.rootDir, new File( tempDir, 'xdoc-temp.xml' ) ) - def asciidocIndexPath = relativePath( project.rootDir, new File( tempAsciidocDir, "$docName/index.txt" ) ) - args = [ - '--attribute', 'revnumber=' + project.version, - '--attribute', 'level1=' + (docType.equals('article') ? 1 : 0), - '--attribute', 'level2=' + (docType.equals('article') ? 2 : 1), - '--attribute', 'level3=' + (docType.equals('article') ? 3 : 2), - '--attribute', 'level4=' + (docType.equals('article') ? 4 : 3), - '--attribute', 'importdir=' + commonResourcesPath, - '--backend', 'docbook', - '--attribute', 'docinfo1', - '--doctype', docType, - '--conf-file=' + asciidocConfigPath, - '--conf-file=' + docbookConfigPath, - '--conf-file=' + linkimagesConfigPath, - '--out-file', xdocOutputPath, - asciidocIndexPath - ] - } - } - - def void generateChunkedHtml() - { - project.copy { - from commonResourcesDir - into outputDir - include '**' - } - project.copy { - from "$docsDir/$docName/resources" - into outputDir - include '**' - } - - project.exec { - def xsltFile = "$docsDir/$docName/xsl/chunked.xsl" - def outputPath = relativePath( project.projectDir, outputDir ) + '/' - executable = 'xsltproc' - args = [ - '--nonet', - '--noout', - '--output', outputPath, - xsltFile, - "$tempDir/xdoc-temp.xml" - ] - } - } - - def void generateSingleHtml() - { - project.exec { - // XML_CATALOG_FILES= - String xsltFile = "$xslDir/xhtml.xsl" - executable = 'xsltproc' - args = [ - '--nonet', - '--noout', - '--output', "$outputDir/${docName}.html", - xsltFile, - "$tempDir/xdoc-temp.xml" - ] - } - } - - def void generatePdf() - { - // $ xsltproc --nonet ../docbook-xsl/fo.xsl article.xml > article.fo - // $ fop article.fo article.pdf - project.exec { - String xsltFile = "$xslDir/fo.xsl" - executable = 'xsltproc' - args = [ - '--nonet', - '--output', "$tempDir/${docName}.fo", - xsltFile, - "$tempDir/xdoc-temp.xml" - ] - } - project.exec { - executable = 'fop' - args = [ - "$tempDir/${docName}.fo", - "$outputDir/${docName}.pdf" - ] - } - } - - def String relativePath( File root, File target ) - { - new File( root.toURI().relativize( target.toURI() ).toString() ).path - } -} http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/buildSrc/src/main/groovy/org/qi4j/gradle/plugin/ModuleReleaseSpecification.groovy ---------------------------------------------------------------------- diff --git a/buildSrc/src/main/groovy/org/qi4j/gradle/plugin/ModuleReleaseSpecification.groovy b/buildSrc/src/main/groovy/org/qi4j/gradle/plugin/ModuleReleaseSpecification.groovy deleted file mode 100644 index 1a3e180..0000000 --- a/buildSrc/src/main/groovy/org/qi4j/gradle/plugin/ModuleReleaseSpecification.groovy +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2011, Niclas Hedhman. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, - * either express or implied. - * See the License for the specific language governing permissions - * and limitations under the License. - */ -package org.qi4j.gradle.plugin; - -import org.gradle.api.Project - -class ModuleReleaseSpecification -{ - def boolean satisfiedBy( Project project ) - { - def devStatusFile = new File( project.projectDir, "dev-status.xml" ) - if( !devStatusFile.exists() ) - { - return false - } - def module = new XmlSlurper().parse( devStatusFile ) - def codebase = module.status.codebase.text() - def docs = module.status.documentation.text() - def tests = module.status.unittests.text() - def satisfied = ( codebase == 'none' && docs == 'complete' && tests != 'complete' ) - satisfied |= ( codebase == 'early' && ( docs == 'complete' || docs == 'good') && (tests == 'complete' || tests == 'good' ) ) - satisfied |= ( codebase == 'beta' && (docs == 'complete' || docs == 'good' || docs == 'brief') && (tests == 'complete' || tests == 'good' || tests == 'some') ) - satisfied |= ( codebase == 'stable' ) - satisfied |= ( codebase == 'mature' ) - println "$project.name($satisfied) -> $codebase, $docs, $tests" - return satisfied - } -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/api/src/main/java/org/apache/zest/api/Qi4j.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/apache/zest/api/Qi4j.java b/core/api/src/main/java/org/apache/zest/api/Qi4j.java new file mode 100644 index 0000000..470c166 --- /dev/null +++ b/core/api/src/main/java/org/apache/zest/api/Qi4j.java @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2007, Rickard Öberg. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.apache.zest.api; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Proxy; +import org.apache.zest.api.association.AbstractAssociation; +import org.apache.zest.api.association.AssociationDescriptor; +import org.apache.zest.api.composite.Composite; +import org.apache.zest.api.composite.CompositeDescriptor; +import org.apache.zest.api.composite.CompositeInstance; +import org.apache.zest.api.composite.InvalidCompositeException; +import org.apache.zest.api.composite.ModelDescriptor; +import org.apache.zest.api.composite.TransientDescriptor; +import org.apache.zest.api.entity.EntityDescriptor; +import org.apache.zest.api.property.Property; +import org.apache.zest.api.property.PropertyDescriptor; +import org.apache.zest.api.service.ServiceDescriptor; +import org.apache.zest.api.structure.Module; +import org.apache.zest.api.value.ValueDescriptor; +import org.apache.zest.functional.Function; + +/** + * Encapsulation of the Zest API. + */ +public interface Qi4j +{ + /** + * If a Modifier gets a reference to the Composite using @This, + * then that reference must be dereferenced using this method + * before handing it out for others to use. + * + * @param Parameterized type of the Composite + * @param composite instance reference injected in Modified using @This + * + * @return the dereferenced Composite + */ + T dereference( T composite ); + + /** + * Returns the Module or UnitOfWork where the Composite belongs. + * + * @param compositeOrUow The Composite (Service, Value, Entity or Transient) or UnitOfWork to lookup the Module it + * belongs to. + * + * @return The Module instance where the Composite or UnitOfWork belongs to. + */ + Module moduleOf( Object compositeOrUow ); + + /** + * Returns the ModelDescriptor of the Composite. + * + * @param compositeOrServiceReference The Composite (Service, Value, Entity or Transient) for which to lookup the + * ModelDescriptor + * + * @return The ModelDescriptor of the Composite + */ + ModelDescriptor modelDescriptorFor( Object compositeOrServiceReference ); + + /** + * Returns the CompositeDescriptor of the Composite. + * + * @param compositeOrServiceReference The Composite (Service, Value, Entity or Transient) for which to lookup the + * CompositeDescriptor + * + * @return The CompositeDescriptor of the Composite + */ + CompositeDescriptor compositeDescriptorFor( Object compositeOrServiceReference ); + + /** + * Returns the TransientDescriptor of the TransientComposite. + * + * @param transsient The TransientComposite for which to lookup the TransientDescriptor + * + * @return The TransientDescriptor of the TransientComposite + */ + TransientDescriptor transientDescriptorFor( Object transsient ); + + /** + * Returns the EntityDescriptor of the EntityComposite. + * + * @param entity The EntityComposite for which to lookup the EntityDescriptor + * + * @return The EntityDescriptor of the EntityComposite + */ + EntityDescriptor entityDescriptorFor( Object entity ); + + /** + * Returns the ValueDescriptor of the ValueComposite. + * + * @param value The ValueComposite for which to lookup the ValueDescriptor + * + * @return The ValueDescriptor of the ValueComposite + */ + ValueDescriptor valueDescriptorFor( Object value ); + + /** + * Returns the ServiceDescriptor of the ServiceComposite. + * + * @param service The ServiceComposite for which to lookup the ServiceDescriptor + * + * @return The ServiceDescriptor of the ServiceComposite + */ + ServiceDescriptor serviceDescriptorFor( Object service ); + + /** + * Returns the PropertyDescriptor of the Property. + * + * @param property The Property for which to lookup the PropertyDescriptor + * + * @return The PropertyDescriptor of the Property + */ + PropertyDescriptor propertyDescriptorFor( Property property ); + + /** + * Returns the AssociationDescriptor of the Association. + * + * @param association The Association for which to lookup the AssociationDescriptor + * + * @return The AssociationDescriptor of the Association + */ + AssociationDescriptor associationDescriptorFor( AbstractAssociation association ); + + /** + * Function that returns the CompositeDescriptor of a Composite. + */ + Function FUNCTION_DESCRIPTOR_FOR = new Function() + { + @Override + public CompositeDescriptor map( Composite composite ) + { + if( composite instanceof Proxy ) + { + InvocationHandler invocationHandler = Proxy.getInvocationHandler( composite ); + return ( (CompositeInstance) invocationHandler ).descriptor(); + } + try + { + Class compositeClass = composite.getClass(); + Field instanceField = compositeClass.getField( "_instance" ); + Object instance = instanceField.get( composite ); + return ( (CompositeInstance) instance ).descriptor(); + } + catch( Exception e ) + { + InvalidCompositeException exception = new InvalidCompositeException( "Could not get _instance field" ); + exception.initCause( e ); + throw exception; + } + } + }; + + /** + * Function that returns the CompositeInstance of a Composite. + */ + Function FUNCTION_COMPOSITE_INSTANCE_OF = new Function() + { + @Override + public CompositeInstance map( Composite composite ) + { + if( composite instanceof Proxy ) + { + return ( (CompositeInstance) Proxy.getInvocationHandler( composite ) ); + } + try + { + Class compositeClass = composite.getClass(); + Field instanceField = compositeClass.getField( "_instance" ); + Object instance = instanceField.get( composite ); + return (CompositeInstance) instance; + } + catch( Exception e ) + { + InvalidCompositeException exception = new InvalidCompositeException( "Could not get _instance field" ); + exception.initCause( e ); + throw exception; + } + } + }; +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/api/src/main/java/org/apache/zest/api/activation/Activation.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/apache/zest/api/activation/Activation.java b/core/api/src/main/java/org/apache/zest/api/activation/Activation.java new file mode 100644 index 0000000..5be35e7 --- /dev/null +++ b/core/api/src/main/java/org/apache/zest/api/activation/Activation.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2011, Rickard Öberg. + * Copyright (c) 2012, Niclas Hedhman. + * Copyright (c) 2012, Paul Merlin. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.apache.zest.api.activation; + +/** + * Interface used by Structure elements and Services that can be activated and passivated. + *

Application and Layer expose this interface so you can activate and passivate them.

+ *

Module and ServiceComposite activation/passivation is handled by the Zest runtime.

+ */ +public interface Activation +{ + /** + * Activate. + *

Fail fast execution order is:

+ *
    + *
  • Fire {@link ActivationEvent.EventType#ACTIVATING}
  • + *
  • Call {@link Activator#beforeActivation(java.lang.Object)} on each Activator
  • + *
  • Call {@link #activate()} children
  • + *
  • Call {@link Activator#afterActivation(java.lang.Object)} on each Activator
  • + *
  • Fire {@link ActivationEvent.EventType#ACTIVATED}
  • + *
+ *

If an Exception is thrown, already activated nodes are passivated.

+ * @throws ActivationException with first Exception of activation plus the PassivationException if any + */ + void activate() + throws ActivationException; + + /** + * Passivate. + *

Fail safe execution order is:

+ *
    + *
  • Fire {@link ActivationEvent.EventType#PASSIVATING}
  • + *
  • Call {@link Activator#beforePassivation(java.lang.Object)} on each Activator
  • + *
  • Call {@link #passivate()} children
  • + *
  • Call {@link Activator#afterPassivation(java.lang.Object)} on each Activator
  • + *
  • Fire {@link ActivationEvent.EventType#PASSIVATED}
  • + *
+ * @throws PassivationException after passivation with all Exceptions of passivation if any + */ + void passivate() + throws PassivationException; +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/api/src/main/java/org/apache/zest/api/activation/ActivationEvent.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/apache/zest/api/activation/ActivationEvent.java b/core/api/src/main/java/org/apache/zest/api/activation/ActivationEvent.java new file mode 100644 index 0000000..c54f4b8 --- /dev/null +++ b/core/api/src/main/java/org/apache/zest/api/activation/ActivationEvent.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2011, Rickard Öberg. + * Copyright (c) 2012, Niclas Hedhman. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.apache.zest.api.activation; + +/** + * ActivationEvents are fired during activation and passivation of instances in Zest. + */ +public final class ActivationEvent +{ + public enum EventType + { + ACTIVATING, ACTIVATED, PASSIVATING, PASSIVATED + } + + private final long timestamp; + private final Object source; + private final EventType type; + + public ActivationEvent( Object source, EventType type ) + { + this.timestamp = System.currentTimeMillis(); + this.source = source; + this.type = type; + } + + /** + * @return the source of the Activation event + */ + public Object source() + { + return source; + } + + /** + * @return the type of the Activation event + */ + public EventType type() + { + return type; + } + + /** + * @return an informative message describing the event + */ + public String message() + { + switch( type ) + { + case ACTIVATING: + return "Activating " + source; + case ACTIVATED: + return "Activated " + source; + case PASSIVATING: + return "Passivating " + source; + case PASSIVATED: + return "Passivated " + source; + } + return ""; + } + + /** + * @see #message() + */ + @Override + public String toString() + { + return message(); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/api/src/main/java/org/apache/zest/api/activation/ActivationEventListener.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/apache/zest/api/activation/ActivationEventListener.java b/core/api/src/main/java/org/apache/zest/api/activation/ActivationEventListener.java new file mode 100644 index 0000000..a6e3bb1 --- /dev/null +++ b/core/api/src/main/java/org/apache/zest/api/activation/ActivationEventListener.java @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2011, Rickard Öberg. + * Copyright (c) 2012, Niclas Hedhman. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.apache.zest.api.activation; + +/** + * Listener for ActivationEvent events + */ +public interface ActivationEventListener +{ + void onEvent( ActivationEvent event ) + throws Exception; +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/api/src/main/java/org/apache/zest/api/activation/ActivationEventListenerRegistration.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/apache/zest/api/activation/ActivationEventListenerRegistration.java b/core/api/src/main/java/org/apache/zest/api/activation/ActivationEventListenerRegistration.java new file mode 100644 index 0000000..c7d0c2a --- /dev/null +++ b/core/api/src/main/java/org/apache/zest/api/activation/ActivationEventListenerRegistration.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2011, Rickard Öberg. + * Copyright (c) 2012, Niclas Hedhman. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.apache.zest.api.activation; + +/** + * Use this to register listeners for ActivationEvents. + * + * This is implemented by Application, Layer, Module, for example. + */ +public interface ActivationEventListenerRegistration +{ + /** + * @param listener will be notified when Activation events occur + */ + void registerActivationEventListener( ActivationEventListener listener ); + + /** + * @param listener will not be notified when Activation events occur anymore + */ + void deregisterActivationEventListener( ActivationEventListener listener ); +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/api/src/main/java/org/apache/zest/api/activation/ActivationException.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/apache/zest/api/activation/ActivationException.java b/core/api/src/main/java/org/apache/zest/api/activation/ActivationException.java new file mode 100644 index 0000000..0008ec9 --- /dev/null +++ b/core/api/src/main/java/org/apache/zest/api/activation/ActivationException.java @@ -0,0 +1,30 @@ +/* + * Copyright 2013 Niclas Hedhman. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.zest.api.activation; + +/** + * Thrown when unable to activate. + */ +public class ActivationException extends Exception +{ + private static final long serialVersionUID = 1L; + public ActivationException( String message, Throwable cause ) + { + super( message, cause ); + } +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/api/src/main/java/org/apache/zest/api/activation/Activator.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/apache/zest/api/activation/Activator.java b/core/api/src/main/java/org/apache/zest/api/activation/Activator.java new file mode 100644 index 0000000..a57b353 --- /dev/null +++ b/core/api/src/main/java/org/apache/zest/api/activation/Activator.java @@ -0,0 +1,54 @@ +/* + * Copyright 2012 Paul Merlin. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.zest.api.activation; + +/** + * Assemble Activators to hook Services Activation. + * + * @param Type of the activatee. + * + * @see ActivatorAdapter + * @see org.apache.zest.api.service.ServiceActivation + */ +public interface Activator +{ + + /** + * Called before activatee activation. + */ + void beforeActivation( ActivateeType activating ) + throws Exception; + + /** + * Called after activatee activation. + */ + void afterActivation( ActivateeType activated ) + throws Exception; + + /** + * Called before activatee passivation. + */ + void beforePassivation( ActivateeType passivating ) + throws Exception; + + /** + * Called after activatee passivation. + */ + void afterPassivation( ActivateeType passivated ) + throws Exception; +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/api/src/main/java/org/apache/zest/api/activation/ActivatorAdapter.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/apache/zest/api/activation/ActivatorAdapter.java b/core/api/src/main/java/org/apache/zest/api/activation/ActivatorAdapter.java new file mode 100644 index 0000000..666b6ec --- /dev/null +++ b/core/api/src/main/java/org/apache/zest/api/activation/ActivatorAdapter.java @@ -0,0 +1,68 @@ +/* + * Copyright 2012 Paul Merlin. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.zest.api.activation; + +/** + * Adapter for Activator. + *

If you are thinking about Service activation, see {@link org.apache.zest.api.service.ServiceActivatorAdapter}.

+ * + * @param Type of the activatee. + */ +public class ActivatorAdapter + implements Activator +{ + /** + * Called before activatee activation. + * @param activating Activating activatee + */ + @Override + public void beforeActivation( ActivateeType activating ) + throws Exception + { + } + + /** + * Called after activatee activation. + * @param activated Activating activatee + */ + @Override + public void afterActivation( ActivateeType activated ) + throws Exception + { + } + + /** + * Called before activatee passivation. + * @param passivating Passivating activatee + */ + @Override + public void beforePassivation( ActivateeType passivating ) + throws Exception + { + } + + /** + * Called after activatee passivation. + * @param passivated Passivated activatee + */ + @Override + public void afterPassivation( ActivateeType passivated ) + throws Exception + { + } +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/api/src/main/java/org/apache/zest/api/activation/ActivatorDescriptor.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/apache/zest/api/activation/ActivatorDescriptor.java b/core/api/src/main/java/org/apache/zest/api/activation/ActivatorDescriptor.java new file mode 100644 index 0000000..e6da0b2 --- /dev/null +++ b/core/api/src/main/java/org/apache/zest/api/activation/ActivatorDescriptor.java @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2014, Paul Merlin. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.zest.api.activation; + +/** + * Activator Descriptor. + */ +public interface ActivatorDescriptor +{ +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/api/src/main/java/org/apache/zest/api/activation/Activators.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/apache/zest/api/activation/Activators.java b/core/api/src/main/java/org/apache/zest/api/activation/Activators.java new file mode 100644 index 0000000..d62b989 --- /dev/null +++ b/core/api/src/main/java/org/apache/zest/api/activation/Activators.java @@ -0,0 +1,39 @@ +/* + * Copyright 2012 Paul Merlin. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.zest.api.activation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * This annotation is used in ServiceComposites to declare Activator implementation classes. + */ +@Retention( RetentionPolicy.RUNTIME ) +@Target( ElementType.TYPE ) +@Documented +public @interface Activators +{ + + /** + * @return Activator implementation classes. + */ + Class>[] value(); +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/api/src/main/java/org/apache/zest/api/activation/ApplicationPassivationThread.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/apache/zest/api/activation/ApplicationPassivationThread.java b/core/api/src/main/java/org/apache/zest/api/activation/ApplicationPassivationThread.java new file mode 100644 index 0000000..f8bbf12 --- /dev/null +++ b/core/api/src/main/java/org/apache/zest/api/activation/ApplicationPassivationThread.java @@ -0,0 +1,112 @@ +/* + * Copyright 2013 Paul Merlin. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.zest.api.activation; + +import java.io.PrintStream; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.apache.zest.api.structure.Application; + +/** + * Application Passivation Thread to use as a Shutdown Hook. + *
Runtime.getRuntime().addShutdownHook( new ApplicationPassivationThread( application ) );
+ *

Constructors to control where errors are logged are provided. They support PrintStream (STDOUT/STDERR) and SLF4J + * Loggers. Defaults to STDERR.

+ */ +public final class ApplicationPassivationThread + extends Thread +{ + /** + * Create a new Application Passivation Thread that output errors to STDERR. + * @param application The Application to passivate + */ + public ApplicationPassivationThread( final Application application ) + { + this( application, null, null ); + } + + /** + * Create a new Application Passivation Thread that output errors to a Logger. + * @param application The Application to passivate + * @param logger Logger for errors + */ + public ApplicationPassivationThread( Application application, Logger logger ) + { + this( application, null, logger ); + } + + /** + * Create a new Application Passivation Thread that output errors to a PrintStream. + * @param application The Application to passivate + * @param output PrintStream for errors + */ + public ApplicationPassivationThread( Application application, PrintStream output ) + { + this( application, output, null ); + } + + private ApplicationPassivationThread( Application application, PrintStream output, Logger logger ) + { + super( new ApplicationPassivation( application, output, logger ), + application.name() + " Passivation Thread" ); + } + + private static class ApplicationPassivation + implements Runnable + { + + private final Application application; + private final PrintStream output; + private final Logger logger; + + private ApplicationPassivation( Application application, PrintStream output, Logger logger ) + { + this.application = application; + this.output = output; + this.logger = logger; + } + + @Override + public void run() + { + try + { + application.passivate(); + } + catch( PassivationException ex ) + { + String message = application.name() + " " + ex.getMessage(); + if( logger != null ) + { + logger.log( Level.SEVERE, message, ex ); + } + else if( output != null ) + { + output.println( message ); + ex.printStackTrace( output ); + } + else + { + ex.printStackTrace(); + } + } + } + + } + +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/api/src/main/java/org/apache/zest/api/activation/PassivationException.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/apache/zest/api/activation/PassivationException.java b/core/api/src/main/java/org/apache/zest/api/activation/PassivationException.java new file mode 100644 index 0000000..7b5d195 --- /dev/null +++ b/core/api/src/main/java/org/apache/zest/api/activation/PassivationException.java @@ -0,0 +1,59 @@ +/* + * Copyright 2009 Niclas Hedhman. + * Copyright 2013 Paul Merlin. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.zest.api.activation; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * Thrown when unable to passivate. + * + * Printed StackTrace contains all causes in order as suppressed exceptions. + */ +public final class PassivationException + extends Exception +{ + + private static final long serialVersionUID = 1L; + private final List causes; + + /** + * Create new PassivationException. + * @param exceptions All exceptions encountered during passivation, in order + */ + public PassivationException( Collection exceptions ) + { + super( "Passivation Exception - [has " + exceptions.size() + " cause(s)]" ); + for( Throwable cause : exceptions ) + { + addSuppressed( cause ); + } + this.causes = new ArrayList<>( exceptions ); + } + + /** + * @return All exceptions encountered during passivation, in order + */ + public List causes() + { + return causes; + } + +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/api/src/main/java/org/apache/zest/api/activation/package.html ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/apache/zest/api/activation/package.html b/core/api/src/main/java/org/apache/zest/api/activation/package.html new file mode 100644 index 0000000..47b333a --- /dev/null +++ b/core/api/src/main/java/org/apache/zest/api/activation/package.html @@ -0,0 +1,26 @@ + + + +

Activation API.

+

+ The Activation API package contains types used by client code to integrate with the Zest™ Runtime activation + mechanism. In assembly, client code can easily listen to Structure (Application, Layers and Modules) and + Services activation events, or, declare Structure and Service Activators. +

+ + http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/api/src/main/java/org/apache/zest/api/association/AbstractAssociation.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/apache/zest/api/association/AbstractAssociation.java b/core/api/src/main/java/org/apache/zest/api/association/AbstractAssociation.java new file mode 100644 index 0000000..d97cf55 --- /dev/null +++ b/core/api/src/main/java/org/apache/zest/api/association/AbstractAssociation.java @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2007, Rickard Öberg. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.zest.api.association; + +/** + * Base interface for all associations. + */ +public interface AbstractAssociation +{ +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/api/src/main/java/org/apache/zest/api/association/Association.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/apache/zest/api/association/Association.java b/core/api/src/main/java/org/apache/zest/api/association/Association.java new file mode 100644 index 0000000..10ededb --- /dev/null +++ b/core/api/src/main/java/org/apache/zest/api/association/Association.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2007, Rickard Öberg. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.zest.api.association; + +import org.apache.zest.api.entity.EntityReference; + +/** + * Association to a single EntityComposite. + */ +public interface Association extends AbstractAssociation +{ + /** + * Get the associated entity. + * + * @return the associated entity + */ + T get(); + + /** + * Set the associated entity. + * + * @param associated the entity + * + * @throws IllegalArgumentException thrown if the entity is not a valid reference for this association + * @throws IllegalStateException thrown if association is immutable + */ + void set( T associated ) + throws IllegalArgumentException, IllegalStateException; + + /** + * @return the the reference of the associated entity. + */ + EntityReference reference(); +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/api/src/main/java/org/apache/zest/api/association/AssociationDescriptor.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/apache/zest/api/association/AssociationDescriptor.java b/core/api/src/main/java/org/apache/zest/api/association/AssociationDescriptor.java new file mode 100644 index 0000000..5c8cbb1 --- /dev/null +++ b/core/api/src/main/java/org/apache/zest/api/association/AssociationDescriptor.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2007, Rickard Öberg. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.zest.api.association; + +import java.lang.reflect.AccessibleObject; +import java.lang.reflect.Type; +import org.apache.zest.api.common.QualifiedName; +import org.apache.zest.api.structure.MetaInfoHolder; + +/** + * Association Descriptor. + */ +public interface AssociationDescriptor extends MetaInfoHolder +{ + /** + * Get the qualified name of the association. This is constructed by + * concatenating the name of the declaring interface with the name + * of the method, using ":" as separator. + *

+ * Example: + *

+ *

+ * com.somecompany.MyInterface with association method + *

+ *

+     * Association<String> someAssociation();
+     * 
+ * will have the qualified name: + *

+     * com.somecompany.MyInterface:someAssociation
+     * 
+ * + * @return the qualified name of the association + */ + QualifiedName qualifiedName(); + + /** + * Get the type of the associated Entities + * + * @return the type of the associated Entities + */ + Type type(); + + boolean isImmutable(); + + boolean isAggregated(); + + AccessibleObject accessor(); + + boolean queryable(); +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/api/src/main/java/org/apache/zest/api/association/AssociationMixin.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/apache/zest/api/association/AssociationMixin.java b/core/api/src/main/java/org/apache/zest/api/association/AssociationMixin.java new file mode 100644 index 0000000..c6079fd --- /dev/null +++ b/core/api/src/main/java/org/apache/zest/api/association/AssociationMixin.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2007, Rickard Öberg. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.zest.api.association; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import org.apache.zest.api.common.AppliesTo; +import org.apache.zest.api.common.AppliesToFilter; +import org.apache.zest.api.injection.scope.State; + +/** + * Generic mixin for associations. + */ +@AppliesTo( { AssociationMixin.AssociationFilter.class } ) +public final class AssociationMixin + implements InvocationHandler +{ + @State + private AssociationStateHolder associations; + + @Override + public Object invoke( Object proxy, Method method, Object[] args ) + throws Throwable + { + return associations.associationFor( method ); + } + + /** + * Associations generic mixin AppliesToFilter. + */ + public static class AssociationFilter + implements AppliesToFilter + { + @Override + public boolean appliesTo( Method method, Class mixin, Class compositeType, Class modifierClass ) + { + return Association.class.isAssignableFrom( method.getReturnType() ); + } + } +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/api/src/main/java/org/apache/zest/api/association/AssociationStateDescriptor.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/apache/zest/api/association/AssociationStateDescriptor.java b/core/api/src/main/java/org/apache/zest/api/association/AssociationStateDescriptor.java new file mode 100644 index 0000000..a6609da --- /dev/null +++ b/core/api/src/main/java/org/apache/zest/api/association/AssociationStateDescriptor.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2008-2011, Rickard Öberg. All Rights Reserved. + * Copyright (c) 2008-2013, Niclas Hedhman. All Rights Reserved. + * Copyright (c) 2014, Paul Merlin. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.zest.api.association; + +import org.apache.zest.api.common.QualifiedName; +import org.apache.zest.api.composite.StateDescriptor; + +/** + * Associations State Descriptor. + */ +public interface AssociationStateDescriptor extends StateDescriptor +{ + AssociationDescriptor getAssociationByName( String name ) + throws IllegalArgumentException; + + AssociationDescriptor getAssociationByQualifiedName( QualifiedName name ) + throws IllegalArgumentException; + + AssociationDescriptor getManyAssociationByName( String name ) + throws IllegalArgumentException; + + AssociationDescriptor getManyAssociationByQualifiedName( QualifiedName name ) + throws IllegalArgumentException; + + AssociationDescriptor getNamedAssociationByName( String name ) + throws IllegalArgumentException; + + AssociationDescriptor getNamedAssociationByQualifiedName( QualifiedName name ) + throws IllegalArgumentException; + + Iterable associations(); + + Iterable manyAssociations(); + + Iterable namedAssociations(); +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/api/src/main/java/org/apache/zest/api/association/AssociationStateHolder.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/apache/zest/api/association/AssociationStateHolder.java b/core/api/src/main/java/org/apache/zest/api/association/AssociationStateHolder.java new file mode 100644 index 0000000..2a9c035 --- /dev/null +++ b/core/api/src/main/java/org/apache/zest/api/association/AssociationStateHolder.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2008-2013, Niclas Hedhman. All Rights Reserved. + * Copyright (c) 2014, Paul Merlin. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.zest.api.association; + +import java.lang.reflect.AccessibleObject; +import org.apache.zest.api.property.StateHolder; + +/** + * This represents the state of a entity (properties+associations). + */ +public interface AssociationStateHolder + extends StateHolder +{ + /** + * Get an association for a specific accessor method + * + * @param associationMethod for the association + * + * @return the association + */ + Association associationFor( AccessibleObject associationMethod ); + + /** + * Get all associations + * + * @return iterable of associations + */ + Iterable> allAssociations(); + + /** + * Get a many-association for a specific accessor method + * + * @param manyassociationMethod for the many-association + * + * @return the association + */ + ManyAssociation manyAssociationFor( AccessibleObject manyassociationMethod ); + + /** + * Get all ManyAssociations + * + * @return iterable of many-associations + */ + Iterable> allManyAssociations(); + + /** + * Get a named-association for a specific accessor method + * + * @param namedassociationMethod for the named-association + * + * @return the association + */ + NamedAssociation namedAssociationFor( AccessibleObject namedassociationMethod ); + + /** + * Get all NmaedAssociations + * + * @return iterable of named-associations + */ + Iterable> allNamedAssociations(); +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/api/src/main/java/org/apache/zest/api/association/AssociationWrapper.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/apache/zest/api/association/AssociationWrapper.java b/core/api/src/main/java/org/apache/zest/api/association/AssociationWrapper.java new file mode 100644 index 0000000..600756f --- /dev/null +++ b/core/api/src/main/java/org/apache/zest/api/association/AssociationWrapper.java @@ -0,0 +1,79 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.zest.api.association; + +import org.apache.zest.api.entity.EntityReference; + +/** + * If you want to catch getting and setting association, then create a GenericConcern + * that wraps the Zest-supplied Association instance with AssociationWrappers. Override + * get() and/or set() to perform your custom code. + */ +public class AssociationWrapper + implements Association +{ + protected Association next; + + public AssociationWrapper( Association next ) + { + this.next = next; + } + + public Association next() + { + return next; + } + + @Override + public Object get() + { + return next.get(); + } + + @Override + public void set( Object associated ) + throws IllegalArgumentException + { + next.set( associated ); + } + + @Override + public EntityReference reference() + { + return next.reference(); + } + + @Override + public int hashCode() + { + return next.hashCode(); + } + + @Override + public boolean equals( Object obj ) + { + return next.equals( obj ); + } + + @Override + public String toString() + { + return next.toString(); + } +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/api/src/main/java/org/apache/zest/api/association/GenericAssociationInfo.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/apache/zest/api/association/GenericAssociationInfo.java b/core/api/src/main/java/org/apache/zest/api/association/GenericAssociationInfo.java new file mode 100644 index 0000000..8641cc5 --- /dev/null +++ b/core/api/src/main/java/org/apache/zest/api/association/GenericAssociationInfo.java @@ -0,0 +1,58 @@ +/* + * Copyright 2008 Niclas Hedhman. All rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.zest.api.association; + +import java.lang.reflect.AccessibleObject; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; + +import static org.apache.zest.api.util.Classes.typeOf; + +/** + * Generic Association info. + */ +public final class GenericAssociationInfo +{ + public static Type associationTypeOf( AccessibleObject accessor ) + { + return toAssociationType( typeOf( accessor ) ); + } + + public static Type toAssociationType( Type methodReturnType ) + { + if( methodReturnType instanceof ParameterizedType ) + { + ParameterizedType parameterizedType = (ParameterizedType) methodReturnType; + if( AbstractAssociation.class.isAssignableFrom( (Class) parameterizedType.getRawType() ) ) + { + return parameterizedType.getActualTypeArguments()[ 0 ]; + } + } + + Type[] interfaces = ( (Class) methodReturnType ).getGenericInterfaces(); + for( Type anInterface : interfaces ) + { + Type associationType = toAssociationType( anInterface ); + if( associationType != null ) + { + return associationType; + } + } + return null; + } +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/api/src/main/java/org/apache/zest/api/association/ManyAssociation.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/apache/zest/api/association/ManyAssociation.java b/core/api/src/main/java/org/apache/zest/api/association/ManyAssociation.java new file mode 100644 index 0000000..e24681f --- /dev/null +++ b/core/api/src/main/java/org/apache/zest/api/association/ManyAssociation.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2007, Rickard Öberg. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.zest.api.association; + +import java.util.List; +import java.util.Set; +import org.apache.zest.api.entity.EntityReference; + +/** + * Association to a collection of entities. + */ +public interface ManyAssociation extends Iterable, AbstractAssociation +{ + /** + * Returns the number of references in this association. + * @return the number of references in this association. + */ + int count(); + + boolean contains( T entity ); + + boolean add( int i, T entity ); + + boolean add( T entity ); + + boolean remove( T entity ); + + T get( int i ); + + List toList(); + + Set toSet(); + + /** + * Returns an unmodifiable Iterable of the references to the associated entities. + * @return the references to the associated entities. + */ + Iterable references(); +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/api/src/main/java/org/apache/zest/api/association/ManyAssociationMixin.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/apache/zest/api/association/ManyAssociationMixin.java b/core/api/src/main/java/org/apache/zest/api/association/ManyAssociationMixin.java new file mode 100644 index 0000000..9d79dbd --- /dev/null +++ b/core/api/src/main/java/org/apache/zest/api/association/ManyAssociationMixin.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2007, Rickard Öberg. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.zest.api.association; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import org.apache.zest.api.common.AppliesTo; +import org.apache.zest.api.common.AppliesToFilter; +import org.apache.zest.api.injection.scope.State; + +/** + * Generic mixin for associations. + */ +@AppliesTo( { ManyAssociationMixin.AssociationFilter.class } ) +public final class ManyAssociationMixin + implements InvocationHandler +{ + @State + private AssociationStateHolder associations; + + @Override + public Object invoke( Object proxy, Method method, Object[] args ) + throws Throwable + { + return associations.manyAssociationFor( method ); + } + + /** + * ManyAssociations generic mixin AppliesToFilter. + */ + public static class AssociationFilter + implements AppliesToFilter + { + @Override + public boolean appliesTo( Method method, Class mixin, Class compositeType, Class modifierClass ) + { + return ManyAssociation.class.isAssignableFrom( method.getReturnType() ); + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/api/src/main/java/org/apache/zest/api/association/ManyAssociationWrapper.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/apache/zest/api/association/ManyAssociationWrapper.java b/core/api/src/main/java/org/apache/zest/api/association/ManyAssociationWrapper.java new file mode 100644 index 0000000..3f29dd4 --- /dev/null +++ b/core/api/src/main/java/org/apache/zest/api/association/ManyAssociationWrapper.java @@ -0,0 +1,123 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.zest.api.association; + +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import org.apache.zest.api.entity.EntityReference; + +/** + * If you want to catch calls to ManyAssociations, then create a GenericConcern + * that wraps the Zest-supplied ManyAssociation instance with ManyAssociationWrappers. Override + * methods to perform your custom code. + */ +public class ManyAssociationWrapper + implements ManyAssociation +{ + protected ManyAssociation next; + + public ManyAssociationWrapper( ManyAssociation next ) + { + this.next = next; + } + + public ManyAssociation next() + { + return next; + } + + @Override + public int count() + { + return next.count(); + } + + @Override + public boolean contains( Object entity ) + { + return next.contains( entity ); + } + + @Override + public boolean add( int i, Object entity ) + { + return next.add( i, entity ); + } + + @Override + public boolean add( Object entity ) + { + return next.add( entity ); + } + + @Override + public boolean remove( Object entity ) + { + return next.remove( entity ); + } + + @Override + public Object get( int i ) + { + return next.get( i ); + } + + @Override + public List toList() + { + return next.toList(); + } + + @Override + public Set toSet() + { + return next.toSet(); + } + + @Override + public Iterable references() + { + return next.references(); + } + + @Override + public Iterator iterator() + { + return next.iterator(); + } + + @Override + public int hashCode() + { + return next.hashCode(); + } + + @Override + public boolean equals( Object obj ) + { + return next.equals( obj ); + } + + @Override + public String toString() + { + return next.toString(); + } +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/api/src/main/java/org/apache/zest/api/association/NamedAssociation.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/apache/zest/api/association/NamedAssociation.java b/core/api/src/main/java/org/apache/zest/api/association/NamedAssociation.java new file mode 100644 index 0000000..ed31e29 --- /dev/null +++ b/core/api/src/main/java/org/apache/zest/api/association/NamedAssociation.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2011-2012, Niclas Hedhman. All Rights Reserved. + * Copyright (c) 2014, Paul Merlin. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.zest.api.association; + +import java.util.Map; +import org.apache.zest.api.entity.EntityReference; + +/** + * Association to named Entities. + * The Iterable<String> returns the names in the association set. + * @param Parameterized associatee type + */ +public interface NamedAssociation + extends Iterable, AbstractAssociation +{ + /** + * @return The number of named associations in this NamedAssociation. + */ + int count(); + + /** + * Checks if there is an association with the given name. + * @param name The name of the association we are checking if it exists. + * @return true if it exists, false otherwise + */ + boolean containsName( String name ); + + /** + * Adds a named assocation. + * @param name The name of the association. + * @param entity The entity for this named association. + * @return true if putted, false otherwise + */ + boolean put( String name, T entity ); + + /** + * Remove a named association. + * @param name The name of the association. + * @return true if removed, false otherwise + */ + boolean remove( String name ); + + /** + * Retrieves a named association. + * @param name The name of the association. + * @return The entity that has previously been associated. + */ + T get( String name ); + + /** + * Checks if the entity is present. + * Note that this is potentially a very slow operation, depending on the size of the NamedAssociation. + * @param entity The entity to look for. + * @return The name of the entity if found, otherwise null. + */ + String nameOf( T entity ); + + /** + * @return A fully populated Map with the content of this NamedAssociation. + */ + Map toMap(); + + /** + * Returns an unmodifiable Iterable of the references to the associated entities. + * @return the references to the associated entities. + */ + Iterable references(); + + /** Returns the EntityReference for the Association with the given name. + * + * @param name The name of the association to return the EntityReference for + * @return The EntityReference of the association. + */ + EntityReference referenceOf( String name ); +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/api/src/main/java/org/apache/zest/api/association/NamedAssociationMixin.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/apache/zest/api/association/NamedAssociationMixin.java b/core/api/src/main/java/org/apache/zest/api/association/NamedAssociationMixin.java new file mode 100644 index 0000000..b289497 --- /dev/null +++ b/core/api/src/main/java/org/apache/zest/api/association/NamedAssociationMixin.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2011-2012, Niclas Hedhman. All Rights Reserved. + * Copyright (c) 2014, Paul Merlin. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.zest.api.association; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import org.apache.zest.api.common.AppliesTo; +import org.apache.zest.api.common.AppliesToFilter; +import org.apache.zest.api.injection.scope.State; + +/** + * Generic mixin for NamedAssociations. + */ +@AppliesTo( NamedAssociationMixin.AssociationFilter.class ) +public final class NamedAssociationMixin + implements InvocationHandler +{ + @State + private AssociationStateHolder associations; + + @Override + public Object invoke( Object proxy, Method method, Object[] args ) + throws Throwable + { + return associations.namedAssociationFor( method ); + } + + /** + * NamedAssociations generic mixin AppliesToFilter. + */ + public static class AssociationFilter + implements AppliesToFilter + { + @Override + public boolean appliesTo( Method method, Class mixin, Class compositeType, Class modifierClass ) + { + return NamedAssociation.class.isAssignableFrom( method.getReturnType() ); + } + } + +}