| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you 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.felix.ipojo.manipulation; |
| |
| import java.io.File; |
| import java.io.FileOutputStream; |
| import java.io.InputStream; |
| import java.net.URL; |
| import java.util.HashMap; |
| import java.util.logging.Level; |
| |
| import org.apache.felix.ipojo.plugin.IPojoPluginConfiguration; |
| import org.objectweb.asm.ClassReader; |
| import org.objectweb.asm.ClassWriter; |
| |
| /** |
| * iPOJO Bytecode Manipulator. |
| * @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a> |
| * |
| */ |
| public class Manipulator { |
| /** |
| * Store the visited fields : [name fo the field, type of the field]. |
| */ |
| private HashMap m_fields = new HashMap(); |
| |
| /** |
| * Store the interface implemented by the class. |
| */ |
| private String[] m_interfaces = new String[0]; |
| |
| /** |
| * Return the hashmap [name of the field, type of the field]. |
| * This information is found when the class is manipulated |
| * It is a clone of the original hashmap to avoid modification by handlers |
| * @return the hashmap [name of the field, type of the field]. |
| */ |
| public HashMap getFields() { |
| return (HashMap)m_fields.clone(); |
| } |
| |
| /** |
| * Return the hashmap [name of the field, type of the field]. |
| * This information is found when the class is manipulated |
| * It is a clone of the original hashmap to avoid modification by handlers |
| * @return the hashmap [name of the field, type of the field]. |
| */ |
| public String[] getInterfaces() { return (String[])m_interfaces.clone(); } |
| |
| /** |
| * Manipulate the class. |
| * @param bundle The component's m_bundle |
| * @param name The name of the class |
| * @param cm The component manager attached to this manipulation |
| * @throws Exception : throwed if the manipulation failed. |
| */ |
| public boolean preProcess(String name, File outputDirectory) throws Exception { |
| |
| // gets an input stream to read the bytecode of the class |
| String path = outputDirectory+"/"+name.replace('.', '/') + ".class"; |
| File clazz = new File(path); |
| |
| if(!clazz.exists()) { return false; } |
| |
| URL url = clazz.toURI().toURL(); |
| |
| //if (url == null) { throw new ClassNotFoundException(name); } |
| IPojoPluginConfiguration.getLogger().log(Level.INFO, "Manipulate the class file : " + clazz.getAbsolutePath()); |
| |
| InputStream is1 = url.openStream(); |
| |
| |
| // First check if the class is already manipulated : |
| ClassReader ckReader = new ClassReader(is1); |
| ClassChecker ck = new ClassChecker(); |
| ckReader.accept(ck, true); |
| is1.close(); |
| |
| m_fields = ck.getFields(); |
| m_interfaces = new String[ck.getInterfaces().length]; |
| for (int i = 0; i < m_interfaces.length; i++) { |
| m_interfaces[i] = ck.getInterfaces()[i].replace('/', '.'); |
| } |
| |
| if(!ck.isalreadyManipulated()) { |
| |
| //Manipulation -> |
| // Add the _setComponentManager method |
| // Instrument all fields |
| InputStream is2 = url.openStream(); |
| ClassReader cr0 = new ClassReader(is2); |
| ClassWriter cw0 = new ClassWriter(true); |
| PreprocessClassAdapter preprocess = new PreprocessClassAdapter(cw0); |
| cr0.accept(preprocess, false); |
| is2.close(); |
| |
| File file = null; |
| try { |
| file = new File(url.getFile()); |
| |
| //file.createNewFile(); |
| FileOutputStream fos = new FileOutputStream(file); |
| |
| fos.write(cw0.toByteArray()); |
| |
| fos.close(); |
| IPojoPluginConfiguration.getLogger().log(Level.INFO, "Put the file " + file.getAbsolutePath() + " in the jar file"); |
| } catch (Exception e) { System.err.println("Problem to write the adapted class on the file system " + " [ "+ file.getAbsolutePath() +" ] " + e.getMessage()); } |
| } |
| // The file is in the bundle |
| return true; |
| } |
| |
| |
| } |