001 /* 002 * Copyright 2006 Stephen J. McConnell. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 013 * implied. 014 * 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 019 package net.dpml.lang; 020 021 import dpml.lang.Part; 022 023 import java.io.IOException; 024 import java.io.OutputStream; 025 import java.io.OutputStreamWriter; 026 import java.io.Writer; 027 import java.net.URI; 028 import java.net.URL; 029 import java.net.URLConnection; 030 import java.util.ServiceLoader; 031 032 import javax.xml.XMLConstants; 033 034 import net.dpml.transit.Artifact; 035 import net.dpml.transit.Transit; 036 037 import net.dpml.runtime.ComponentStrategyHandler; 038 import net.dpml.util.Logger; 039 040 import dpml.util.DefaultLogger; 041 import dpml.util.ElementHelper; 042 043 import org.w3c.dom.Element; 044 import org.w3c.dom.TypeInfo; 045 046 /** 047 * Abstract component deployment strategy. 048 * 049 * @author <a href="http://www.dpml.net">Digital Product Management Laboratory</a> 050 * @version 2.0.1 051 */ 052 public abstract class Strategy implements Comparable<Strategy> 053 { 054 private static final Logger LOGGER = new DefaultLogger( "dpml.lang" ); 055 056 /** 057 * Creation of a new management strategy. 058 * 059 * @param subject the implementation class to be managed 060 * @param registry the service registry 061 * @param name the path under which the strategy will be established 062 * @return the management strategy 063 * @exception Exception if a general loading error occurs 064 */ 065 public static Strategy load( Class<?> subject, ServiceRegistry registry, String name ) throws Exception 066 { 067 if( null == subject ) 068 { 069 throw new NullPointerException( "subject" ); 070 } 071 StrategyHandler handler = PartContentHandler.getStrategyHandler( subject ); 072 Strategy strategy = handler.newStrategy( subject, name ); 073 if( null == registry ) 074 { 075 StandardServiceRegistry standard = new StandardServiceRegistry(); 076 strategy.initialize( standard ); 077 } 078 else 079 { 080 strategy.initialize( registry ); 081 } 082 return strategy; 083 } 084 085 /** 086 * Load a strategy defined by the supplied uri. 087 * 088 * @param uri the source uri to a part definition 089 * @return the strategy 090 * @exception Exception if a general loading error occurs 091 * @exception NullPointerException if the uri argument is null 092 */ 093 public static Strategy load( URI uri ) throws Exception, NullPointerException 094 { 095 return load( null, null, uri, null ); 096 } 097 098 /** 099 * Load a strategy defined by the supplied uri, name, classloader and service 100 * registry, and return a value assignable to the supplied type. 101 * 102 * @param classloader the anchor classloader 103 * @param registry the service registry 104 * @param uri the source uri to a part definition 105 * @param name the path under which the strategy will be established 106 * @return an instance of the supplied type 107 * @exception Exception if a general loading error occurs 108 * @exception NullPointerException if the uri argument is null 109 */ 110 public static Strategy load( 111 ClassLoader classloader, ServiceRegistry registry, URI uri, String name ) throws Exception, NullPointerException 112 { 113 if( null == uri ) 114 { 115 throw new NullPointerException( "uri" ); 116 } 117 Transit transit = Transit.getInstance(); 118 URL url = Artifact.toURL( uri ); 119 URLConnection connection = url.openConnection(); 120 Part part = PartContentHandler.getPartContent( classloader, connection, name, true ); 121 Strategy strategy = part.getStrategy(); 122 if( null == registry ) 123 { 124 StandardServiceRegistry standard = new StandardServiceRegistry(); 125 strategy.initialize( standard ); 126 } 127 else 128 { 129 strategy.initialize( registry ); 130 } 131 return strategy; 132 } 133 134 //-------------------------------------------------------------------- 135 // state 136 //-------------------------------------------------------------------- 137 138 private ClassLoader m_classloader; 139 140 //-------------------------------------------------------------------- 141 // constructor 142 //-------------------------------------------------------------------- 143 144 /** 145 * Creation of a new deployment strategy. 146 * @param classloader the classloader 147 */ 148 protected Strategy( ClassLoader classloader ) 149 { 150 m_classloader = classloader; 151 } 152 153 //-------------------------------------------------------------------- 154 // public operations 155 //-------------------------------------------------------------------- 156 157 /** 158 * Return the classloader establised by the strategy implementation. 159 * @return the classloader 160 */ 161 public ClassLoader getClassLoader() 162 { 163 return m_classloader; 164 } 165 166 /** 167 * Return the priority assigned to this strategy. 168 * @return the priority value 169 */ 170 public abstract int getPriority(); 171 172 /** 173 * Return true if this strategy is a candidate with result to the 174 * supply of an instance assignable to the supplied type. 175 * 176 * @param type the requested type 177 * @return type if this strategy is a condidate 178 */ 179 public abstract boolean isaCandidate( Class<?> type ); 180 181 /** 182 * Instantiate a service returning an instance assigned to the supplied type. 183 * 184 * @param type the return type 185 * @return an instance of the type 186 */ 187 public abstract <T>T getInstance( Class<T> type ); 188 189 /** 190 * Write the strategy to the supplied buffer in XML format. 191 * @param buffer the output buffer 192 * @param key the optional identifying key 193 * @exception IOException if an IO error occurs 194 */ 195 public abstract void encode( Buffer buffer, String key ) throws IOException; 196 197 /** 198 * Composite strategies are strategy implementations that contain subidary 199 * strategies. During lookup operations, a subsidiary strategy may request 200 * a service from the enclosing strategy. To enable traversal from a subsidary 201 * to enclosing context a service registry shall be provided to all subsidiary 202 * strategies. 203 * 204 * @param registry the service registry 205 */ 206 public abstract void initialize( ServiceRegistry registry ); 207 208 /** 209 * Return the short name of this strategy. 210 * @return the name 211 */ 212 public abstract String getName(); 213 214 /** 215 * Compares a supplied strategy with this strategy. If the supplied 216 * strategy has a priority greater than this strategy the returned value 217 * is 1, otherwise if the supplied strategy has a priority lower than this 218 * strategy then the return value is -1,otherwise the returned value is 0. 219 * 220 * @param strategy the strategy to evaluate relative to this strategy 221 * @return the priority comparative index 222 */ 223 public int compareTo( Strategy strategy ) 224 { 225 int n = getPriority(); 226 int m = strategy.getPriority(); 227 if( n > m ) 228 { 229 return -1; 230 } 231 else if( n == m ) 232 { 233 return 0; 234 } 235 else 236 { 237 return 1; 238 } 239 } 240 241 //-------------------------------------------------------------------- 242 // protected operations 243 //-------------------------------------------------------------------- 244 245 /** 246 * Return a value assignable to the supplied type or null if the type 247 * cannot be resolved from this strategy. 248 * @param c the target class 249 * @return an instance of the class or null 250 * @exception IOException if an IO error occurs 251 */ 252 public abstract <T>T getContentForClass( Class<T> c ) throws IOException; 253 254 //-------------------------------------------------------------------- 255 // private implementation 256 //-------------------------------------------------------------------- 257 258 }