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 <ActivateeType> Type of the activatee. + * + * @see ActivatorAdapter + * @see org.qi4j.api.service.ServiceActivation + */ +public interface Activator<ActivateeType> +{ + + /** + * 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. + * <p>If you are thinking about Service activation, see {@link org.qi4j.api.service.ServiceActivatorAdapter}.</p> + * + * @param <ActivateeType> Type of the activatee. + */ +public class ActivatorAdapter<ActivateeType> + implements Activator<ActivateeType> +{ + /** + * 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<? extends Activator<?>>[] 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. + * <pre>Runtime.getRuntime().addShutdownHook( new ApplicationPassivationThread( application ) );</pre> + * <p>Constructors to control where errors are logged are provided. They support PrintStream (STDOUT/STDERR) and SLF4J + * Loggers. Defaults to STDERR.</p> + */ +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<Exception> causes; + + /** + * Create new PassivationException. + * @param exceptions All exceptions encountered during passivation, in order + */ + public PassivationException( Collection<Exception> 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<Exception> 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 @@ +<!-- +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. +--> +<html> + <body> + <h2>Activation API.</h2> + <p> + 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. + </p> + </body> +</html> 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<T> 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. + * <p> + * Example: + * </p> + * <p> + * com.somecompany.MyInterface with association method + * </p> + * <pre><code> + * Association<String> someAssociation(); + * </code></pre> + * will have the qualified name: + * <pre><code> + * com.somecompany.MyInterface:someAssociation + * </code></pre> + * + * @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<? extends AssociationDescriptor> associations(); + + Iterable<? extends AssociationDescriptor> manyAssociations(); + + Iterable<? extends AssociationDescriptor> 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 + */ + <T> Association<T> associationFor( AccessibleObject associationMethod ); + + /** + * Get all associations + * + * @return iterable of associations + */ + Iterable<? extends Association<?>> allAssociations(); + + /** + * Get a many-association for a specific accessor method + * + * @param manyassociationMethod for the many-association + * + * @return the association + */ + <T> ManyAssociation<T> manyAssociationFor( AccessibleObject manyassociationMethod ); + + /** + * Get all ManyAssociations + * + * @return iterable of many-associations + */ + Iterable<? extends ManyAssociation<?>> allManyAssociations(); + + /** + * Get a named-association for a specific accessor method + * + * @param namedassociationMethod for the named-association + * + * @return the association + */ + <T> NamedAssociation<T> namedAssociationFor( AccessibleObject namedassociationMethod ); + + /** + * Get all NmaedAssociations + * + * @return iterable of named-associations + */ + Iterable<? extends NamedAssociation<?>> 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<Object> +{ + protected Association<Object> next; + + public AssociationWrapper( Association<Object> next ) + { + this.next = next; + } + + public Association<Object> 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<T> extends Iterable<T>, 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<T> toList(); + + Set<T> toSet(); + + /** + * Returns an unmodifiable Iterable of the references to the associated entities. + * @return the references to the associated entities. + */ + Iterable<EntityReference> 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<Object> +{ + protected ManyAssociation<Object> next; + + public ManyAssociationWrapper( ManyAssociation<Object> next ) + { + this.next = next; + } + + public ManyAssociation<Object> 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<Object> toList() + { + return next.toList(); + } + + @Override + public Set<Object> toSet() + { + return next.toSet(); + } + + @Override + public Iterable<EntityReference> references() + { + return next.references(); + } + + @Override + public Iterator<Object> 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 <T> Parameterized associatee type + */ +public interface NamedAssociation<T> + extends Iterable<String>, 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<String, T> toMap(); + + /** + * Returns an unmodifiable Iterable of the references to the associated entities. + * @return the references to the associated entities. + */ + Iterable<EntityReference> 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<Object> +{ + protected NamedAssociation<Object> next; + + public NamedAssociationWrapper( NamedAssociation<Object> next ) + { + this.next = next; + } + + public NamedAssociation<Object> next() + { + return next; + } + + @Override + public Iterator<String> 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<String, Object> toMap() + { + return next.toMap(); + } + + @Override + public Iterable<EntityReference> 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 @@ +<!-- +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. +--> +<html> + <body> + <h2>Association API.</h2> + </body> +</html> 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 <i>cacheOnRead</i> 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 <i>cacheOnRead</i> 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 @@ +<!-- +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. +--> +<html> + <body> + <h2>Cache API.</h2> + <p> + The Cache API/SPI is an extension point for Entity Store caching. + </p> + <p> + 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; + </p> +<pre><code> +public void assemble( ModuleAssembly module ) +{ + CacheOptions options = new CacheOptions( true, true, false ); + module.addServices( EhCacheService.class ).setMetaInfo( options ); +} +</code></pre> + <p> + 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. + </p> + </body> +</html> \ 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. + * <p> + * @AppliesTo can specify one of; + * </p> + * <ul> + * <li>An annotation,</li> + * <li>An interface,</li> + * <li>An AppliesToFilter implementation.</li> + * </ul> + * <p> + * Example with annotation: + * </p> + * <pre><code> + * + * @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 + * {} + * </code></pre> + * <p> + * 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. + * </p> + */ +@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. + * <p> + * 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. + * </p> + * <p> + * 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; + * </p> + * <pre><code> + * @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" ); + * } + * } + * </code></pre> + * <p> + * 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. + * </p> + */ +public interface AppliesToFilter +{ + /** + * This is an internal AppliesToFilter which is assigned if no other AppliesToFilters are found for a given + * fragment. + * <p> + * There is no reason for user code to use this AppliesToFilter directly, and should be perceived as an + * internal class in Zest. + * </p> + */ + 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; + * <ul> + * <li>private constructor.</li> + * <li>abstract class for Constraints.</li> + * <li>interface instead of a class.</li> + * <li>useful constructor missing.</li> + * <li>exception thrown in the constructor.</li> + * <li>Subclassing of org.qi4j.api.property.Property</li> + * </ul> + * <p> + * See the nested exception for additional details. + * </p> + */ +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. + * <p> + * <strong>This is effectively an internal class and should not be used directly.</strong> + * </p> + * <p> + * 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. + * </p> + * <p> + * To set the MetaInfo on a Composite, call the {@code setMetaInfo()} methods on the various composite declaration + * types, such as; + * </p> + * <pre><code> + * public void assemble( ModuleAssembly module ) + * throws AssemblyException + * { + * Map<String,String> properties = ...; + * module.services( MyService.class ).setMetaInfo( properties ); + * } + * </code></pre> + * <p> + * which can later be retrieved by calling the {@code metaInfo()} method on the composite itself. For the example + * above that would be; + * </p> + * <pre><code> + * @Mixins(MyServiceMixin.class) + * public interface MyService extends ServiceComposite + * { + * + * } + * + * public abstract class MyServiceMixin + * implements MyService + * { + * private Properties props; + * + * public MyServiceMixin() + * { + * props = metaInfo( Map.class ); + * } + * } + * </code></pre> + */ +public final class MetaInfo +{ + private final static Collection<Class> ignored; + + static + { + ignored = new HashSet<Class>( 4, 0.8f ); // Optimize size used. + ignored.addAll( asList( Mixins.class, Concerns.class, SideEffects.class ) ); + } + + private final Map<Class<?>, Object> metaInfoMap; + + public MetaInfo() + { + metaInfoMap = new LinkedHashMap<Class<?>, Object>(); + } + + public MetaInfo( MetaInfo metaInfo ) + { + metaInfoMap = new LinkedHashMap<Class<?>, 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<Type> types = typesOf( metaInfoclass ); + for( Type type : types ) + { + metaInfoMap.put( Classes.RAW_CLASS.map( type ), metaInfo ); + } + } + } + + public <T> T get( Class<T> metaInfoType ) + { + return metaInfoType.cast( metaInfoMap.get( metaInfoType ) ); + } + + public <T> void add( Class<T> 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. + * <ul> + * <li> + * If applied to a method parameter, then the value is allowed to be null. Default + * is that method parameters have to be non-null. + * </li> + * <li> + * 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. + * </li> + * <li> + * If applied to an injected member field, it is allowed tha none get injected. For instance, an <code>@Optional + * @Service</code> would allow a service to not have been declared and the field will be null. + * </li> + * </ul> + * <p> + * 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. + * </p> + * <p> + * Example; + * </p> + * <pre><code> + * @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. + * + * </code></pre> + */ +@Retention( RetentionPolicy.RUNTIME ) +@Target( { ElementType.PARAMETER, ElementType.METHOD, ElementType.FIELD } ) +@Documented +public @interface Optional +{ +} \ No newline at end of file
