001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019package org.apache.commons.weaver.model; 020 021import java.io.IOException; 022import java.io.InputStream; 023import java.io.OutputStream; 024import java.util.Properties; 025import java.util.logging.Logger; 026 027import javax.activation.DataSource; 028 029import org.apache.commons.lang3.Validate; 030import org.apache.commons.weaver.spi.Cleaner; 031import org.apache.commons.weaver.spi.Weaver; 032 033/** 034 * Encapsulates the environment in which a {@link Weaver} or {@link Cleaner} must operate. 035 */ 036public abstract class WeaveEnvironment { 037 private static final String CONTENT_TYPE = "application/octet-stream"; 038 039 private class Resource implements DataSource { 040 private final String name; 041 042 Resource(final String name) { 043 this.name = name; 044 } 045 046 /** 047 * Get the content type, always "application/octet-stream". 048 * @return {@link String} 049 */ 050 @Override 051 public String getContentType() { 052 return CONTENT_TYPE; 053 } 054 055 /** 056 * Get an {@link InputStream} for reading this {@link Resource}. 057 */ 058 @Override 059 public InputStream getInputStream() throws IOException { 060 return classLoader.getResourceAsStream(name); 061 } 062 063 /** 064 * Get the name of this {@link Resource}. 065 * @return {@link String} 066 */ 067 @Override 068 public String getName() { 069 return name; 070 } 071 072 /** 073 * Get an {@link OutputStream} for writing to this {@link Resource}. 074 * @return {@link OutputStream} 075 */ 076 @Override 077 public OutputStream getOutputStream() throws IOException { 078 return WeaveEnvironment.this.getOutputStream(name); 079 } 080 } 081 082 /** 083 * ClassLoader containing scannable and weavable classes. 084 */ 085 public final ClassLoader classLoader; 086 087 /** 088 * Configuration properties. By convention, any configuration property should start with its name, e.g. 089 * "privilizer". 090 */ 091 public final Properties config; 092 093 private final Logger log; 094 095 /** 096 * Create a new {@link WeaveEnvironment}. 097 * @param classLoader property 098 * @param config property 099 * @param log property 100 */ 101 protected WeaveEnvironment(final ClassLoader classLoader, final Properties config, final Logger log) { 102 super(); 103 this.classLoader = classLoader; 104 this.config = (Properties) Validate.notNull(config, "config").clone(); 105 this.log = log; 106 } 107 108 /** 109 * Handle a debug message. 110 * @param message text 111 * @param args format 112 * @see String#format(String, Object...) 113 */ 114 public void debug(final String message, final Object... args) { 115 log.fine(String.format(message, args)); 116 } 117 118 /** 119 * Handle a verbose message. 120 * @param message text 121 * @param args format 122 * @see String#format(String, Object...) 123 */ 124 public void verbose(final String message, final Object... args) { 125 log.fine(String.format(message, args)); 126 } 127 128 /** 129 * Handle a warning message. 130 * @param message text 131 * @param args format 132 * @see String#format(String, Object...) 133 */ 134 public void warn(final String message, final Object... args) { 135 log.warning(String.format(message, args)); 136 } 137 138 /** 139 * Handle an info message. 140 * @param message text 141 * @param args format 142 * @see String#format(String, Object...) 143 */ 144 public void info(final String message, final Object... args) { 145 log.info(String.format(message, args)); 146 } 147 148 /** 149 * Handle an error message. 150 * @param message text 151 * @param args format 152 * @see String#format(String, Object...) 153 */ 154 public void error(final String message, final Object... args) { 155 log.severe(String.format(message, args)); 156 } 157 158 /** 159 * Get a {@link DataSource} representing {@code cls}. 160 * @param cls type 161 * @return {@link DataSource} 162 */ 163 public final DataSource getClassfile(final Class<?> cls) { 164 return getClassfile(cls.getName()); 165 } 166 167 /** 168 * Get a {@link DataSource} for the specified class. 169 * @param classname of type 170 * @return {@link DataSource} 171 */ 172 public final DataSource getClassfile(final String classname) { 173 return getResource(getResourceName(classname)); 174 } 175 176 /** 177 * Get a {@link DataSource} for the specified resource. 178 * @param name of resource 179 * @return {@link DataSource} 180 */ 181 public final DataSource getResource(final String name) { 182 return new Resource(name); 183 } 184 185 /** 186 * Delete the classfile for {@code cls}. 187 * @param cls type 188 * @return whether successful 189 */ 190 public final boolean deleteClassfile(final Class<?> cls) { 191 return deleteClassfile(cls.getName()); 192 } 193 194 /** 195 * Delete the classfile for the specified class. 196 * @param classname of type 197 * @return whether successful 198 */ 199 public final boolean deleteClassfile(final String classname) { 200 return deleteResource(getResourceName(classname)); 201 } 202 203 /** 204 * Delete the specified resource. 205 * @param name to delete 206 * @return whether successful 207 */ 208 public abstract boolean deleteResource(String name); 209 210 /** 211 * Open an {@link OutputStream} for the specified resource. 212 * @param resourceName to open 213 * @return {@link OutputStream} 214 * @throws IOException on error 215 */ 216 protected abstract OutputStream getOutputStream(String resourceName) throws IOException; 217 218 /** 219 * Convert a classname into a resource name. 220 * @param classname to convert 221 * @return String 222 */ 223 protected static String getResourceName(final String classname) { 224 return classname.replace('.', '/') + ".class"; 225 } 226}