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 A2A7518407 for ; Fri, 31 Jul 2015 02:47:22 +0000 (UTC) Received: (qmail 76426 invoked by uid 500); 31 Jul 2015 02:47:22 -0000 Delivered-To: apmail-zest-commits-archive@zest.apache.org Received: (qmail 76374 invoked by uid 500); 31 Jul 2015 02:47:22 -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 75722 invoked by uid 99); 31 Jul 2015 02:47:21 -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; Fri, 31 Jul 2015 02:47:21 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 686E6DFCC9; Fri, 31 Jul 2015 02:47:21 +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: Fri, 31 Jul 2015 02:47:59 -0000 Message-Id: In-Reply-To: References: X-Mailer: ASF-Git Admin Mailer Subject: [40/51] [abbrv] [partial] zest-java git commit: Revert "First round of changes to move to org.apache.zest namespace." http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/activation/ActivationEventListener.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/activation/ActivationEventListener.java b/core/api/src/main/java/org/qi4j/api/activation/ActivationEventListener.java new file mode 100644 index 0000000..3562c6e --- /dev/null +++ b/core/api/src/main/java/org/qi4j/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.qi4j.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/a789141d/core/api/src/main/java/org/qi4j/api/activation/ActivationEventListenerRegistration.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/activation/ActivationEventListenerRegistration.java b/core/api/src/main/java/org/qi4j/api/activation/ActivationEventListenerRegistration.java new file mode 100644 index 0000000..41e3b5e --- /dev/null +++ b/core/api/src/main/java/org/qi4j/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.qi4j.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/a789141d/core/api/src/main/java/org/qi4j/api/activation/ActivationException.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/activation/ActivationException.java b/core/api/src/main/java/org/qi4j/api/activation/ActivationException.java new file mode 100644 index 0000000..30d06be --- /dev/null +++ b/core/api/src/main/java/org/qi4j/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.qi4j.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/a789141d/core/api/src/main/java/org/qi4j/api/activation/Activator.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/activation/Activator.java b/core/api/src/main/java/org/qi4j/api/activation/Activator.java new file mode 100644 index 0000000..2cba184 --- /dev/null +++ b/core/api/src/main/java/org/qi4j/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.qi4j.api.activation; + +/** + * Assemble Activators to hook Services Activation. + * + * @param Type of the activatee. + * + * @see ActivatorAdapter + * @see org.qi4j.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/a789141d/core/api/src/main/java/org/qi4j/api/activation/ActivatorAdapter.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/activation/ActivatorAdapter.java b/core/api/src/main/java/org/qi4j/api/activation/ActivatorAdapter.java new file mode 100644 index 0000000..59652b9 --- /dev/null +++ b/core/api/src/main/java/org/qi4j/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.qi4j.api.activation; + +/** + * Adapter for Activator. + *

If you are thinking about Service activation, see {@link org.qi4j.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/a789141d/core/api/src/main/java/org/qi4j/api/activation/ActivatorDescriptor.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/activation/ActivatorDescriptor.java b/core/api/src/main/java/org/qi4j/api/activation/ActivatorDescriptor.java new file mode 100644 index 0000000..bfe3fee --- /dev/null +++ b/core/api/src/main/java/org/qi4j/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.qi4j.api.activation; + +/** + * Activator Descriptor. + */ +public interface ActivatorDescriptor +{ +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/activation/Activators.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/activation/Activators.java b/core/api/src/main/java/org/qi4j/api/activation/Activators.java new file mode 100644 index 0000000..8d0f7e6 --- /dev/null +++ b/core/api/src/main/java/org/qi4j/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.qi4j.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/a789141d/core/api/src/main/java/org/qi4j/api/activation/ApplicationPassivationThread.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/activation/ApplicationPassivationThread.java b/core/api/src/main/java/org/qi4j/api/activation/ApplicationPassivationThread.java new file mode 100644 index 0000000..62b1f67 --- /dev/null +++ b/core/api/src/main/java/org/qi4j/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.qi4j.api.activation; + +import java.io.PrintStream; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.qi4j.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/a789141d/core/api/src/main/java/org/qi4j/api/activation/PassivationException.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/activation/PassivationException.java b/core/api/src/main/java/org/qi4j/api/activation/PassivationException.java new file mode 100644 index 0000000..c3f33fe --- /dev/null +++ b/core/api/src/main/java/org/qi4j/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.qi4j.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/a789141d/core/api/src/main/java/org/qi4j/api/activation/package.html ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/activation/package.html b/core/api/src/main/java/org/qi4j/api/activation/package.html new file mode 100644 index 0000000..47b333a --- /dev/null +++ b/core/api/src/main/java/org/qi4j/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/a789141d/core/api/src/main/java/org/qi4j/api/association/AbstractAssociation.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/association/AbstractAssociation.java b/core/api/src/main/java/org/qi4j/api/association/AbstractAssociation.java new file mode 100644 index 0000000..60afce2 --- /dev/null +++ b/core/api/src/main/java/org/qi4j/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.qi4j.api.association; + +/** + * Base interface for all associations. + */ +public interface AbstractAssociation +{ +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/association/Association.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/association/Association.java b/core/api/src/main/java/org/qi4j/api/association/Association.java new file mode 100644 index 0000000..acd406f --- /dev/null +++ b/core/api/src/main/java/org/qi4j/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.qi4j.api.association; + +import org.qi4j.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/a789141d/core/api/src/main/java/org/qi4j/api/association/AssociationDescriptor.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/association/AssociationDescriptor.java b/core/api/src/main/java/org/qi4j/api/association/AssociationDescriptor.java new file mode 100644 index 0000000..9f7576a --- /dev/null +++ b/core/api/src/main/java/org/qi4j/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.qi4j.api.association; + +import java.lang.reflect.AccessibleObject; +import java.lang.reflect.Type; +import org.qi4j.api.common.QualifiedName; +import org.qi4j.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/a789141d/core/api/src/main/java/org/qi4j/api/association/AssociationMixin.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/association/AssociationMixin.java b/core/api/src/main/java/org/qi4j/api/association/AssociationMixin.java new file mode 100644 index 0000000..ac26de3 --- /dev/null +++ b/core/api/src/main/java/org/qi4j/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.qi4j.api.association; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import org.qi4j.api.common.AppliesTo; +import org.qi4j.api.common.AppliesToFilter; +import org.qi4j.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/a789141d/core/api/src/main/java/org/qi4j/api/association/AssociationStateDescriptor.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/association/AssociationStateDescriptor.java b/core/api/src/main/java/org/qi4j/api/association/AssociationStateDescriptor.java new file mode 100644 index 0000000..83c04a4 --- /dev/null +++ b/core/api/src/main/java/org/qi4j/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.qi4j.api.association; + +import org.qi4j.api.common.QualifiedName; +import org.qi4j.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/a789141d/core/api/src/main/java/org/qi4j/api/association/AssociationStateHolder.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/association/AssociationStateHolder.java b/core/api/src/main/java/org/qi4j/api/association/AssociationStateHolder.java new file mode 100644 index 0000000..e33ff7f --- /dev/null +++ b/core/api/src/main/java/org/qi4j/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.qi4j.api.association; + +import java.lang.reflect.AccessibleObject; +import org.qi4j.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/a789141d/core/api/src/main/java/org/qi4j/api/association/AssociationWrapper.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/association/AssociationWrapper.java b/core/api/src/main/java/org/qi4j/api/association/AssociationWrapper.java new file mode 100644 index 0000000..68777b3 --- /dev/null +++ b/core/api/src/main/java/org/qi4j/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.qi4j.api.association; + +import org.qi4j.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/a789141d/core/api/src/main/java/org/qi4j/api/association/GenericAssociationInfo.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/association/GenericAssociationInfo.java b/core/api/src/main/java/org/qi4j/api/association/GenericAssociationInfo.java new file mode 100644 index 0000000..7173547 --- /dev/null +++ b/core/api/src/main/java/org/qi4j/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.qi4j.api.association; + +import java.lang.reflect.AccessibleObject; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; + +import static org.qi4j.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/a789141d/core/api/src/main/java/org/qi4j/api/association/ManyAssociation.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/association/ManyAssociation.java b/core/api/src/main/java/org/qi4j/api/association/ManyAssociation.java new file mode 100644 index 0000000..37d7211 --- /dev/null +++ b/core/api/src/main/java/org/qi4j/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.qi4j.api.association; + +import java.util.List; +import java.util.Set; +import org.qi4j.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/a789141d/core/api/src/main/java/org/qi4j/api/association/ManyAssociationMixin.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/association/ManyAssociationMixin.java b/core/api/src/main/java/org/qi4j/api/association/ManyAssociationMixin.java new file mode 100644 index 0000000..5b2177d --- /dev/null +++ b/core/api/src/main/java/org/qi4j/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.qi4j.api.association; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import org.qi4j.api.common.AppliesTo; +import org.qi4j.api.common.AppliesToFilter; +import org.qi4j.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/a789141d/core/api/src/main/java/org/qi4j/api/association/ManyAssociationWrapper.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/association/ManyAssociationWrapper.java b/core/api/src/main/java/org/qi4j/api/association/ManyAssociationWrapper.java new file mode 100644 index 0000000..aee7804 --- /dev/null +++ b/core/api/src/main/java/org/qi4j/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.qi4j.api.association; + +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import org.qi4j.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/a789141d/core/api/src/main/java/org/qi4j/api/association/NamedAssociation.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/association/NamedAssociation.java b/core/api/src/main/java/org/qi4j/api/association/NamedAssociation.java new file mode 100644 index 0000000..61c9c9a --- /dev/null +++ b/core/api/src/main/java/org/qi4j/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.qi4j.api.association; + +import java.util.Map; +import org.qi4j.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/a789141d/core/api/src/main/java/org/qi4j/api/association/NamedAssociationMixin.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/association/NamedAssociationMixin.java b/core/api/src/main/java/org/qi4j/api/association/NamedAssociationMixin.java new file mode 100644 index 0000000..d612ed6 --- /dev/null +++ b/core/api/src/main/java/org/qi4j/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.qi4j.api.association; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import org.qi4j.api.common.AppliesTo; +import org.qi4j.api.common.AppliesToFilter; +import org.qi4j.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() ); + } + } + +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/association/NamedAssociationWrapper.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/association/NamedAssociationWrapper.java b/core/api/src/main/java/org/qi4j/api/association/NamedAssociationWrapper.java new file mode 100644 index 0000000..814644a --- /dev/null +++ b/core/api/src/main/java/org/qi4j/api/association/NamedAssociationWrapper.java @@ -0,0 +1,122 @@ +/* + * 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.qi4j.api.association; + +import java.util.Iterator; +import java.util.Map; +import org.qi4j.api.entity.EntityReference; + +/** + * If you want to catch calls to NamedAssociations, then create a GenericConcern + * that wraps the Zest-supplied NamedAssociations instance with NamedAssociationsWrapper. Override + * methods to perform your custom code. + */ +public class NamedAssociationWrapper + implements NamedAssociation +{ + protected NamedAssociation next; + + public NamedAssociationWrapper( NamedAssociation next ) + { + this.next = next; + } + + public NamedAssociation next() + { + return next; + } + + @Override + public Iterator iterator() + { + return next.iterator(); + } + + @Override + public int count() + { + return next.count(); + } + + @Override + public boolean containsName( String name ) + { + return next.containsName( name ); + } + + @Override + public boolean put( String name, Object entity ) + { + return next.put( name, entity ); + } + + @Override + public boolean remove( String name ) + { + return next.remove( name ); + } + + @Override + public Object get( String name ) + { + return next.get( name ); + } + + @Override + public String nameOf( Object entity ) + { + return next.nameOf( entity ); + } + + @Override + public Map toMap() + { + return next.toMap(); + } + + @Override + public Iterable references() + { + return next.references(); + } + + @Override + public EntityReference referenceOf( String name ) + { + return next.referenceOf( name ); + } + + @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/a789141d/core/api/src/main/java/org/qi4j/api/association/package.html ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/association/package.html b/core/api/src/main/java/org/qi4j/api/association/package.html new file mode 100644 index 0000000..cf48596 --- /dev/null +++ b/core/api/src/main/java/org/qi4j/api/association/package.html @@ -0,0 +1,21 @@ + + + +

Association API.

+ + http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/cache/CacheOptions.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/cache/CacheOptions.java b/core/api/src/main/java/org/qi4j/api/cache/CacheOptions.java new file mode 100644 index 0000000..ccfc286 --- /dev/null +++ b/core/api/src/main/java/org/qi4j/api/cache/CacheOptions.java @@ -0,0 +1,86 @@ +/* + * Copyright 2010 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.qi4j.api.cache; + +/** + * CacheOptions is a metaInfo class for the Cache system for Entity persistence. + * CacheOptions should be assigned to the Usecase of the UnitOfWork, to give hint on caching to entity stores. + * See {@link org.qi4j.api.usecase.UsecaseBuilder} on how to set the metaInfo on Usecases. + */ +public final class CacheOptions +{ + public static final CacheOptions ALWAYS = new CacheOptions( true, true, true ); + public static final CacheOptions NEVER = new CacheOptions( false, false, false ); + + private final boolean cacheOnRead; + private final boolean cacheOnWrite; + private final boolean cacheOnNew; + + /** + * Constructor for CacheOptions. + * + * @param cacheOnRead if true, give the hint to the Cache system that it may not be a good idea to cache the + * read values. This is useful when it is known that the read will be over a large set and + * shouldn't affect the existing cached entities. For instance, when traversing the EntityStore + * this option is set to false. + * @param cacheOnWrite if true, give the hint to the Cache system that it may not be a good idea to cache the + * entity when the value is updated. If this is false, the cache should be emptied from any + * cached entity instead of updated. There are few cases when this is useful, and if this is + * false, it makes sense that the cacheOnRead is also false. + * @param cacheOnNew if true, give the hint to the Cache system that it may not be a good idea to cache a newly + * created Entity, as it is not likely to be read in the near future. This is useful when + * batch inserts are being made. + */ + public CacheOptions( boolean cacheOnRead, boolean cacheOnWrite, boolean cacheOnNew ) + { + this.cacheOnRead = cacheOnRead; + this.cacheOnWrite = cacheOnWrite; + this.cacheOnNew = cacheOnNew; + } + + /** + * @return if true, give the hint to the Cache system that it may not be a good idea to cache the + * read values. This is useful when it is known that the read will be over a large set and + * shouldn't affect the existing cached entities. For instance, when traversing the EntityStore + */ + public boolean cacheOnRead() + { + return cacheOnRead; + } + + /** + * @return if true, give the hint to the Cache system that it may not be a good idea to cache the + * entity when the value is updated. If this is false, the cache should be emptied from any + * cached entity instead of updated. There are few cases when this is useful, and if this is + * false, it makes sense that the cacheOnRead is also false. + */ + public boolean cacheOnWrite() + { + return cacheOnWrite; + } + + /** + * @return if true, give the hint to the Cache system that it may not be a good idea to cache a newly + * created Entity, as it is not likely to be read in the near future. This is useful when + * batch inserts are being made. + */ + public boolean cacheOnNew() + { + return cacheOnNew; + } +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/cache/package.html ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/cache/package.html b/core/api/src/main/java/org/qi4j/api/cache/package.html new file mode 100644 index 0000000..a62da34 --- /dev/null +++ b/core/api/src/main/java/org/qi4j/api/cache/package.html @@ -0,0 +1,40 @@ + + + +

Cache API.

+

+ The Cache API/SPI is an extension point for Entity Store caching. +

+

+ The API part is only to allow caching options to be passed to the underlying extension in a uniform and + standard way. CacheOptions are to be passed as meta info on the optional Cache extension that is specified + during assembly phase. Example; +

+

+public void assemble( ModuleAssembly module )
+{
+    CacheOptions options = new CacheOptions( true, true, false );
+    module.addServices( EhCacheService.class ).setMetaInfo( options );
+}
+
+

+ Not all EntityStore implementations use the Cache extension, so check the implementation details of the + EntityStore whether the cache extension can bring any benefits or not. +

+ + \ No newline at end of file http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/common/AppliesTo.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/common/AppliesTo.java b/core/api/src/main/java/org/qi4j/api/common/AppliesTo.java new file mode 100644 index 0000000..b23f204 --- /dev/null +++ b/core/api/src/main/java/org/qi4j/api/common/AppliesTo.java @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2007, Rickard Öberg. All Rights Reserved. + * Copyright (c) 2007, 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.api.common; + +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; + +/** + * Fragments that implement InvocationHandler and which should only be applied to methods that have a particular + * annotation or implement a known interface should use this annotation. + *

+ * @AppliesTo can specify one of; + *

+ *
    + *
  • An annotation,
  • + *
  • An interface,
  • + *
  • An AppliesToFilter implementation.
  • + *
+ *

+ * Example with annotation: + *

+ *

+ *
+ * @AppliesTo( Sessional.class )   // Tells Zest to apply this concern on methods with @Sessional annotation
+ * public class SessionConcern extends GenericConcern
+ * {
+ *     public Object invoke( Object proxy, Method method, Object[] args )
+ *         throws Throwable
+ *     {
+ *         ... do session stuff ...
+ *     }
+ * }
+ *
+ * @Retention( RetentionPolicy.RUNTIME )
+ * @Target( ElementType.METHOD )
+ * @Documented
+ * @Inherited
+ * public @interface Sessional
+ * {
+ * }
+ *
+ * public class MyMixin
+ *     implements My
+ * {
+ *     @Sessional
+ *     public void doSomethingSessional()
+ *     {
+ *        // ... do your logic wrapped in a session
+ *     }
+ *
+ *     public void doSomethingWithoutSession()
+ *     {
+ *        // ... do stuff that are not wrapped in session.
+ *     }
+ * }
+ *
+ * public interface My
+ * {
+ *     void doSomethingSessional();
+ *
+ *     void doSomethingWithoutSession();
+ * }
+ *
+ * @Concerns( SessionConcern.class )
+ * @Mixins( MyMixin.class )
+ * public interface MyComposite extends My, TransientComposite
+ * {}
+ * 
+ *

+ * The doSomethingWithoutSession method do not have the @Sessional annotation, therefore the SessionConcern will + * not be placed into the call sequence of these methods, and + * vice-versa. The @Sessional annotation can be placed either on the interface method or the implementation + * method, depending on whether it is a contract or implementation detail. + *

+ */ +@Retention( RetentionPolicy.RUNTIME ) +@Target( { ElementType.TYPE, ElementType.METHOD } ) +@Documented +public @interface AppliesTo +{ + /** + * List of interfaces, annotations or AppliesToFilter + * implementation classes. + * If one of them matches the current element it will be + * accepted, so this list can be considered an "or". + * + * @return array of classes or interfaces to be used by the filter + */ + Class[] value(); +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/common/AppliesToFilter.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/common/AppliesToFilter.java b/core/api/src/main/java/org/qi4j/api/common/AppliesToFilter.java new file mode 100644 index 0000000..f356cf4 --- /dev/null +++ b/core/api/src/main/java/org/qi4j/api/common/AppliesToFilter.java @@ -0,0 +1,83 @@ +/* + * 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.qi4j.api.common; + +import java.lang.reflect.Method; + +/** + * Implementations of this interface can be specified in the @AppliesTo. + *

+ * AppliesTo filters are one of the driving technologies in Zest. They allow you to apply fragments (Mixins, + * Concerns, SideEffects), often generic ones, depending on the context that they are evaluated under. This + * mechanism is heavily used internally in Zest to achieve many other features. + *

+ *

+ * The starting point is the basic use of AppliesToFilter, where the @AppliesTo annotation is given an + * AppliesToFilter implementation as an argument, for instance at a Mixin implementation; + *

+ *

+ * @AppliesTo( MyAppliesToFilter.class )
+ * public class SomeMixin
+ *     implements InvocationHandler
+ * {
+ *
+ * }
+ *
+ * public class MyAppliesToFilter
+ *     implements AppliesToFilter
+ * {
+ *     public boolean appliesTo( Method method, Class<?> mixin, Class<?> compositeType, Class<?> fragmentClass )
+ *     {
+ *         return method.getName().startsWith( "my" );
+ *     }
+ * }
+ * 
+ *

+ * In the case above, the generic mixin will only be applied to the methods that that is defined by the + * AppliesToFilter. This is the primary way to define limits on the application of generic fragments, since + * especially mixins are rarely applied to all methods. + *

+ */ +public interface AppliesToFilter +{ + /** + * This is an internal AppliesToFilter which is assigned if no other AppliesToFilters are found for a given + * fragment. + *

+ * There is no reason for user code to use this AppliesToFilter directly, and should be perceived as an + * internal class in Zest. + *

+ */ + AppliesToFilter ALWAYS = new AppliesToFilter() + { + @Override + public boolean appliesTo( Method method, Class mixin, Class compositeType, Class fragmentClass ) + { + return true; + } + }; + + /** + * Check if the Fragment should be applied or not. Will be call when applied to Mixins, Concerns, SideEffects. + * + * @param method method that is invoked + * @param mixin mixin implementation for the method + * @param compositeType composite type + * @param fragmentClass fragment that is being applies + * + * @return true if the filter passes, otherwise false + */ + boolean appliesTo( Method method, Class mixin, Class compositeType, Class fragmentClass ); +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/common/ConstructionException.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/common/ConstructionException.java b/core/api/src/main/java/org/qi4j/api/common/ConstructionException.java new file mode 100644 index 0000000..9957e63 --- /dev/null +++ b/core/api/src/main/java/org/qi4j/api/common/ConstructionException.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2007, Rickard Öberg. All Rights Reserved. + * Copyright (c) 2007, 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.api.common; + +/** + * Thrown when a Fragment or object could not be instantiated. + * This includes, but not be limited to; + *
    + *
  • private constructor.
  • + *
  • abstract class for Constraints.
  • + *
  • interface instead of a class.
  • + *
  • useful constructor missing.
  • + *
  • exception thrown in the constructor.
  • + *
  • Subclassing of org.qi4j.api.property.Property
  • + *
+ *

+ * See the nested exception for additional details. + *

+ */ +public class ConstructionException + extends RuntimeException +{ + private static final long serialVersionUID = 1L; + + public ConstructionException() + { + } + + public ConstructionException( String message ) + { + super( message ); + } + + public ConstructionException( String message, Throwable cause ) + { + super( message, cause ); + } + + public ConstructionException( Throwable cause ) + { + super( cause ); + } +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/common/InvalidApplicationException.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/common/InvalidApplicationException.java b/core/api/src/main/java/org/qi4j/api/common/InvalidApplicationException.java new file mode 100644 index 0000000..5769fad --- /dev/null +++ b/core/api/src/main/java/org/qi4j/api/common/InvalidApplicationException.java @@ -0,0 +1,36 @@ +/* + * 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.qi4j.api.common; + +/** + * Thrown when an application is considered to not be constructed properly. + * This happens primarily when client code tries to instantiate Composites + * and objects which have not been registered in the ModuleAssembly. + */ +public class InvalidApplicationException + extends RuntimeException +{ + private static final long serialVersionUID = 1L; + + public InvalidApplicationException( String string ) + { + super( string ); + } + + public InvalidApplicationException( String string, Throwable cause ) + { + super( string, cause ); + } +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/common/MetaInfo.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/common/MetaInfo.java b/core/api/src/main/java/org/qi4j/api/common/MetaInfo.java new file mode 100644 index 0000000..b746711 --- /dev/null +++ b/core/api/src/main/java/org/qi4j/api/common/MetaInfo.java @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2008, 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.qi4j.api.common; + +import java.lang.annotation.Annotation; +import java.lang.reflect.AnnotatedElement; +import java.lang.reflect.Type; +import java.util.Collection; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.Map; +import org.qi4j.api.concern.Concerns; +import org.qi4j.api.mixin.Mixins; +import org.qi4j.api.sideeffect.SideEffects; +import org.qi4j.api.util.Classes; + +import static java.util.Arrays.asList; +import static org.qi4j.api.util.Classes.typesOf; + +/** + * Used to declare and access meta-info. + *

+ * This is effectively an internal class and should not be used directly. + *

+ *

+ * MetaInfo can be set on composites during the assembly phase, a.k.a the bootstrap + * process. MetaInfo is any additional data that one wishes to associate at the 'class level' instead of instance + * level of a composite declaration. + *

+ *

+ * To set the MetaInfo on a Composite, call the {@code setMetaInfo()} methods on the various composite declaration + * types, such as; + *

+ *

+ * public void assemble( ModuleAssembly module )
+ *     throws AssemblyException
+ * {
+ *     Map<String,String> properties = ...;
+ *     module.services( MyService.class ).setMetaInfo( properties );
+ * }
+ * 
+ *

+ * which can later be retrieved by calling the {@code metaInfo()} method on the composite itself. For the example + * above that would be; + *

+ *

+ * @Mixins(MyServiceMixin.class)
+ * public interface MyService extends ServiceComposite
+ * {
+ *
+ * }
+ *
+ * public abstract class MyServiceMixin
+ *     implements MyService
+ * {
+ *     private Properties props;
+ *
+ *     public MyServiceMixin()
+ *     {
+ *         props = metaInfo( Map.class );
+ *     }
+ * }
+ * 
+ */ +public final class MetaInfo +{ + private final static Collection ignored; + + static + { + ignored = new HashSet( 4, 0.8f ); // Optimize size used. + ignored.addAll( asList( Mixins.class, Concerns.class, SideEffects.class ) ); + } + + private final Map, Object> metaInfoMap; + + public MetaInfo() + { + metaInfoMap = new LinkedHashMap, Object>(); + } + + public MetaInfo( MetaInfo metaInfo ) + { + metaInfoMap = new LinkedHashMap, Object>(); + metaInfoMap.putAll( metaInfo.metaInfoMap ); + } + + public void set( Object metaInfo ) + { + if( metaInfo instanceof Annotation ) + { + Annotation annotation = (Annotation) metaInfo; + metaInfoMap.put( annotation.annotationType(), metaInfo ); + } + else + { + Class metaInfoclass = metaInfo.getClass(); + Iterable types = typesOf( metaInfoclass ); + for( Type type : types ) + { + metaInfoMap.put( Classes.RAW_CLASS.map( type ), metaInfo ); + } + } + } + + public T get( Class metaInfoType ) + { + return metaInfoType.cast( metaInfoMap.get( metaInfoType ) ); + } + + public void add( Class infoType, T info ) + { + metaInfoMap.put( infoType, info ); + } + + public MetaInfo withAnnotations( AnnotatedElement annotatedElement ) + { + for( Annotation annotation : annotatedElement.getAnnotations() ) + { + if( !ignored.contains( annotation.annotationType() ) + && get( annotation.annotationType() ) == null ) + { + set( annotation ); + } + } + return this; + } + + @Override + public String toString() + { + return metaInfoMap.toString(); + } + + public void remove( Class serviceFinderClass ) + { + metaInfoMap.remove( serviceFinderClass ); + } +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/common/Optional.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/common/Optional.java b/core/api/src/main/java/org/qi4j/api/common/Optional.java new file mode 100644 index 0000000..3a070c3 --- /dev/null +++ b/core/api/src/main/java/org/qi4j/api/common/Optional.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2007, Rickard Öberg. All Rights Reserved. + * Copyright (c) 2007, 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.api.common; + +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; + +/** + * Annotation to denote that something is optional. + *
    + *
  • + * If applied to a method parameter, then the value is allowed to be null. Default + * is that method parameters have to be non-null. + *
  • + *
  • + * If applied to a Property declaration, then the value may be null after construction of + * the instance, or may be set to null at a later time. + *
  • + *
  • + * If applied to an injected member field, it is allowed tha none get injected. For instance, an @Optional + * @Service would allow a service to not have been declared and the field will be null. + *
  • + *
+ *

+ * Optionality is not the default in Zest, and if injections, property values and parameters in methods are not + * non-null, the Zest runtime will throw an {@link org.qi4j.api.constraint.ConstraintViolationException}, indicating + * which field/property/parameter in which composite and mixin the problem has been detected. + *

+ *

+ * Example; + *

+ *

+ * @Optional @Service
+ * MyService service;   // If no MyService instance is declared and visible to this service injection point
+ *                      // the 'service' field will be null.
+ *
+ * @Service
+ * YourService other;   // If no YourService instance is declared and visible to this service injection point
+ *                      // the Zest runtime will throw a ConstraintViolationException.
+ *
+ * 
+ */ +@Retention( RetentionPolicy.RUNTIME ) +@Target( { ElementType.PARAMETER, ElementType.METHOD, ElementType.FIELD } ) +@Documented +public @interface Optional +{ +} \ No newline at end of file