blob: 887e5a7a5919209b4331fca2d43315bdb5a14fb8 [file] [log] [blame]
/*
* Copyright (c) 2009, Niclas Hedhman. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.apache.zest.api.service.qualifier;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import org.apache.zest.api.service.ServiceReference;
import org.apache.zest.functional.Specification;
/**
* Filter services based on Meta Info being declared on the Service.
* <p>
* Meta Info of any type can be set on the service during assembly, e.g.;
* </p>
* <pre><code>
* module.addService( MyService.class ).setMetaInfo( new MyCustomInfo(someData) );
* </code></pre>
* <p>
* and then at an injection point you can do this:
* </p>
* <pre><code>
* &#64;Service &#64;HasMetaInfo(MyCustomInfo.class) MyService service;
* </code></pre>
* <p>
* to get only a service that has a MyCustomInfo instance set as meta info.
* </p>
*/
@Retention( RetentionPolicy.RUNTIME )
@Qualifier( HasMetaInfo.HasMetaInfoQualifier.class )
@Documented
public @interface HasMetaInfo
{
/**
* The Class(es) needed to have been defined in the Service meta info for a qualifier to evaluate true.
*
* @return One or more classes that should be defined in the service's meta info for the service to be considered
* qualified. If more than one class is defined, the {@code anded()} parameter will define if they must be
* AND'ed or OR'ed together.
*/
Class[] value();
/**
* True if the Classes defined in the value() field should be AND'ed instead of OR'ed.
*
* @return If true, all the Class types defined in {@code value()} must be defined for the service for it to be
* qualified. If false, if any of the Class types defined in {@code value()} is defined for the service
* the service is qualified.
*/
boolean anded() default false;
/**
* HasMetaInfo Annotation Qualifier.
* See {@link HasMetaInfo}.
*/
public static class HasMetaInfoQualifier
implements AnnotationQualifier<HasMetaInfo>
{
@Override
public <T> Specification<ServiceReference<?>> qualifier( final HasMetaInfo hasMetaInfo )
{
return new Specification<ServiceReference<?>>()
{
@Override
@SuppressWarnings( {"raw", "unchecked"} )
public boolean satisfiedBy( ServiceReference<?> service )
{
for( Class metaInfoType : hasMetaInfo.value() )
{
Object metaInfo = service.metaInfo( metaInfoType );
if( hasMetaInfo.anded() )
{
if( metaInfo == null )
{
return false;
}
}
else
{
if( metaInfo != null )
{
return true;
}
}
}
return false;
}
};
}
}
}