001// Copyright 2006, 2007, 2008, 2011 The Apache Software Foundation 002// 003// Licensed under the Apache License, Version 2.0 (the "License"); 004// you may not use this file except in compliance with the License. 005// You may obtain a copy of the License at 006// 007// http://www.apache.org/licenses/LICENSE-2.0 008// 009// Unless required by applicable law or agreed to in writing, software 010// distributed under the License is distributed on an "AS IS" BASIS, 011// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 012// See the License for the specific language governing permissions and 013// limitations under the License. 014 015package org.apache.tapestry5.ioc.internal; 016 017import java.lang.reflect.Method; 018import java.util.Set; 019 020import org.apache.tapestry5.func.F; 021import org.apache.tapestry5.func.Flow; 022import org.apache.tapestry5.func.Mapper; 023import org.apache.tapestry5.ioc.AnnotationProvider; 024import org.apache.tapestry5.ioc.ObjectCreator; 025import org.apache.tapestry5.ioc.ServiceBuilderResources; 026import org.apache.tapestry5.ioc.def.ServiceDef; 027import org.apache.tapestry5.ioc.def.ServiceDef3; 028import org.apache.tapestry5.ioc.internal.services.AnnotationProviderChain; 029import org.apache.tapestry5.ioc.internal.util.InternalUtils; 030 031public class ServiceDefImpl implements ServiceDef3 032{ 033 private final Class serviceInterface; 034 035 private final Class serviceImplementation; 036 037 private final String serviceId; 038 039 private final String scope; 040 041 private final boolean eagerLoad; 042 043 private final ObjectCreatorSource source; 044 045 private final Set<Class> markers; 046 047 private final boolean preventDecoration; 048 049 /** 050 * @param serviceInterface 051 * interface implemented by the service (or the service implementation class, for 052 * non-proxied services) 053 * @param serviceImplementation 054 * service implementation class if exists 055 * @param serviceId 056 * unique id for the service 057 * @param markers 058 * set of marker annotation classes (will be retained not copied) 059 * @param scope 060 * scope of the service (i.e., {@link org.apache.tapestry5.ioc.ScopeConstants#DEFAULT}). 061 * @param eagerLoad 062 * if true, the service is realized at startup, rather than on-demand 063 * @param preventDecoration 064 * if true, the service may not be decorated 065 * @param source 066 * used to create the service implementation when needed 067 */ 068 ServiceDefImpl(Class serviceInterface, Class serviceImplementation, String serviceId, Set<Class> markers, 069 String scope, boolean eagerLoad, boolean preventDecoration, ObjectCreatorSource source) 070 { 071 this.serviceInterface = serviceInterface; 072 this.serviceImplementation = serviceImplementation; 073 this.serviceId = serviceId; 074 this.scope = scope; 075 this.eagerLoad = eagerLoad; 076 this.preventDecoration = preventDecoration; 077 this.source = source; 078 079 this.markers = markers; 080 } 081 082 @Override 083 public String toString() 084 { 085 return source.getDescription(); 086 } 087 088 @Override 089 public ObjectCreator createServiceCreator(ServiceBuilderResources resources) 090 { 091 return source.constructCreator(resources); 092 } 093 094 @Override 095 public String getServiceId() 096 { 097 return serviceId; 098 } 099 100 @Override 101 public Class getServiceInterface() 102 { 103 return serviceInterface; 104 } 105 106 @Override 107 public Class getServiceImplementation() 108 { 109 return serviceImplementation; 110 } 111 112 @Override 113 public String getServiceScope() 114 { 115 return scope; 116 } 117 118 @Override 119 public boolean isEagerLoad() 120 { 121 return eagerLoad; 122 } 123 124 @Override 125 public Set<Class> getMarkers() 126 { 127 return markers; 128 } 129 130 @Override 131 public boolean isPreventDecoration() 132 { 133 return preventDecoration; 134 } 135 136 private Flow<Class> searchPath() 137 { 138 return F.flow(serviceImplementation, serviceInterface).removeNulls(); 139 } 140 141 @Override 142 public AnnotationProvider getClassAnnotationProvider() 143 { 144 return AnnotationProviderChain.create(searchPath().map(InternalUtils.CLASS_TO_AP_MAPPER).toList()); 145 } 146 147 @Override 148 public AnnotationProvider getMethodAnnotationProvider(final String methodName, final Class... argumentTypes) 149 { 150 return AnnotationProviderChain.create(searchPath().map(new Mapper<Class, Method>() 151 { 152 @Override 153 public Method map(Class element) 154 { 155 return InternalUtils.findMethod(element, methodName, argumentTypes); 156 } 157 }).map(InternalUtils.METHOD_TO_AP_MAPPER).toList()); 158 } 159 160 @Override 161 public int hashCode() 162 { 163 final int prime = 31; 164 int result = 1; 165 result = prime * result + ((serviceId == null) ? 0 : serviceId.hashCode()); 166 return result; 167 } 168 169 @Override 170 public boolean equals(Object obj) 171 { 172 if (this == obj) { return true; } 173 if (obj == null) { return false; } 174 if (!(obj instanceof ServiceDefImpl)) { return false; } 175 ServiceDef other = (ServiceDef) obj; 176 if (serviceId == null) 177 { 178 if (other.getServiceId() != null) { return false; } 179 } 180 else if (!serviceId.equals(other.getServiceId())) { return false; } 181 return true; 182 } 183 184}