package com.francetelecom.rd.stubs.engine;
/*
* #%L
* Matos
* $Id:$
* $HeadURL:$
* %%
* Copyright (C) 2008 - 2014 Orange SA
* %%
* Licensed 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.
* #L%
*/
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;
/**
* This represents a jar containing an alternative annotation of the currently dumped
* jar. It is mainly used when the representation of the stubs is changed or when the
* version of the profile dumped is changed.
*
* @author Pierre Cregut
*
*/
public class AlternativeImplementation {
private String altPrefix;
private RelocatingClassLoader loader;
Pattern prefixPattern;
private Class<?> origin;
private Class<?> current;
private Map<String,Method> methods = new HashMap<String,Method>();
private Map<String,Constructor<?>> constructors = new HashMap<String,Constructor<?>>();
private Map<String,Field> fields = new HashMap<String,Field>();
/**
* Pattern to get rid of the prefixes.
*/
final public Pattern antipattern;
/**
* Constructor
* @param loader
* @param altPrefix
* @param origPrefix
*/
public AlternativeImplementation(RelocatingClassLoader loader, String altPrefix, String origPrefix) {
this.loader = loader;
this.altPrefix = altPrefix;
prefixPattern = Pattern.compile(origPrefix);
this.antipattern = Pattern.compile("(" + altPrefix + "|" + origPrefix + ")[./]");
}
private String rename(String s) {
return prefixPattern.matcher(s).replaceAll(altPrefix);
}
/**
* Finds the equivalent class in the alternative hierarchy of a class belonging to
* the new hierarchy.
* @param c
* @return
*/
public Class<?> findEquivalent(Class<?> c) {
methods.clear();
constructors.clear();
fields.clear();
try {
origin = c;
current = loader.loadClass(rename (c.getName()));
for(Method m: current.getDeclaredMethods()) {
methods.put(m.toString(), m);
}
for(Constructor<?> co: current.getDeclaredConstructors()) {
constructors.put(co.toString(), co);
}
for(Field fi: current.getDeclaredFields()) {
fields.put(fi.toString(), fi);
}
return current;
} catch (Exception e) {
if (e.getMessage().contains("Conflict")) System.err.println("BOGUS2 " + c.getName());
return null;
}
}
/**
* Same as findEquivalent but, if not found it returns self.
* @param c
* @return
*/
public Class<?> findEquivalentOrSelf(Class <?> c) {
Class <?> alt = findEquivalent(c);
return (alt == null) ? c : alt;
}
/**
* Check if class is present in the alternative hierarchy
* @param c
* @return
*/
public boolean isPresent(Class<?> c) {
methods.clear();
constructors.clear();
fields.clear();
try {
origin = c;
current = loader.loadClass(rename (c.getName()));
for(Method m: current.getDeclaredMethods()) {
methods.put(m.toString(), m);
}
for(Constructor<?> co: current.getDeclaredConstructors()) {
constructors.put(co.toString(), co);
}
for(Field fi: current.getDeclaredFields()) {
fields.put(fi.toString(), fi);
}
return true;
} catch (Exception e) {
if (e.getMessage().contains("Conflict")) System.err.println("BOGUS" + c.getName());
else System.err.println("GEEE " + c.getName());
return false;
}
}
/**
* Finds the equivalent method in the alternative hierarchy of a class belonging to
* the new hierarchy.
* @param m
* @return
*/
public Method findEquivalent(Method m) {
if (!m.getDeclaringClass().equals(origin)) {
if (!isPresent(m.getDeclaringClass())) System.err.println("Class not exist");
}
return methods.get(rename(m.toString()));
}
/**
* Check if method is present in the alternative hierarchy
* @param c
* @return
*/
public boolean isPresent(Method m) {
if (!m.getDeclaringClass().equals(origin)) isPresent(m.getDeclaringClass());
Method alt = methods.get(rename(m.toString()));
return (alt != null);
}
/**
* Finds the equivalent field in the alternative hierarchy of a class belonging to
* the new hierarchy.
* @param f
* @return
*/
public Field findEquivalent(Field f) {
if (!f.getDeclaringClass().equals(origin)) isPresent(f.getDeclaringClass());
return fields.get(rename(f.toString()));
}
/**
* Check if field is present in the alternative hierarchy
* @param c
* @return
*/
public boolean isPresent(Field f) {
if (!f.getDeclaringClass().equals(origin)) isPresent(f.getDeclaringClass());
Field alt = fields.get(rename(f.toString()));
return (alt != null);
}
/**
* Finds the equivalent constructor in the alternative hierarchy of a class belonging to
* the new hierarchy.
* @param c
* @return
*/
public Constructor<?> findEquivalent(Constructor<?> c) {
if (!c.getDeclaringClass().equals(origin)) isPresent(c.getDeclaringClass());
return constructors.get(rename(c.toString()));
}
/**
* Check if constructor is present in the alternative hierarchy
* @param c
* @return
*/
public boolean isPresent(Constructor<?> c) {
if (!c.getDeclaringClass().equals(origin)) isPresent(c.getDeclaringClass());
Constructor <?> alt = constructors.get(rename(c.toString()));
return (alt != null);
}
}