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; 020 021import java.io.File; 022import java.net.URLClassLoader; 023import java.util.ArrayList; 024import java.util.Collections; 025import java.util.LinkedHashSet; 026import java.util.List; 027import java.util.Properties; 028import java.util.ServiceLoader; 029import java.util.Set; 030import java.util.logging.Logger; 031 032import org.apache.commons.lang3.Validate; 033import org.apache.commons.weaver.model.WeaveEnvironment; 034import org.apache.commons.weaver.spi.Weaver; 035import org.apache.commons.weaver.utils.URLArray; 036import org.apache.xbean.finder.archive.FileArchive; 037 038/** 039 * This class discovers and invokes available {@link Weaver} plugins. 040 */ 041public class WeaveProcessor { 042 043 private static final Logger LOG = Logger.getLogger(WeaveProcessor.class.getName()); 044 045 /** 046 * List of picked up weaver plugins. 047 */ 048 private static final List<Weaver> WEAVERS; 049 050 static { 051 final List<Weaver> weavers = new ArrayList<Weaver>(); 052 for (final Weaver weaver : ServiceLoader.load(Weaver.class)) { 053 weavers.add(weaver); 054 } 055 WEAVERS = Collections.unmodifiableList(weavers); 056 } 057 058 /** 059 * The classpath which will be used to look up cross references during weaving. 060 */ 061 private final List<String> classpath; 062 063 /** 064 * The actual path to be woven, replacing any affected classes. 065 */ 066 private final File target; 067 068 /** 069 * Properties for configuring discovered plugin modules. 070 */ 071 private final Properties configuration; 072 073 /** 074 * Create a new {@link WeaveProcessor} instance. 075 * 076 * @param classpath not {@code null} 077 * @param target not {@code null} 078 * @param configuration not {@code null} 079 */ 080 public WeaveProcessor(final List<String> classpath, final File target, final Properties configuration) { 081 super(); 082 this.classpath = Validate.notNull(classpath, "classpath"); 083 this.target = Validate.notNull(target, "target"); 084 Validate.isTrue(!target.exists() || target.isDirectory(), "%s is not a directory", target); 085 this.configuration = Validate.notNull(configuration, "configuration"); 086 } 087 088 /** 089 * Weave classes in target directory. 090 */ 091 public void weave() { 092 if (!target.exists()) { 093 LOG.warning("Target directory " + target + " does not exist; nothing to do!"); 094 } 095 final Set<String> finderClasspath = new LinkedHashSet<String>(); 096 finderClasspath.add(target.getAbsolutePath()); 097 finderClasspath.addAll(classpath); 098 final ClassLoader classLoader = new URLClassLoader(URLArray.fromPaths(finderClasspath)); 099 final Finder finder = new Finder(new FileArchive(classLoader, target)); 100 for (final Weaver weaver : WEAVERS) { 101 final WeaveEnvironment env = 102 new LocalWeaveEnvironment(target, classLoader, configuration, Logger.getLogger(weaver.getClass() 103 .getName())); 104 weaver.process(env, finder); 105 } 106 } 107}