blob: fb2b141089901088070491aa492d5983bc9b2f5b [file] [log] [blame]
/* Copyright 2004 The Apache Software Foundation
*
* 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.
*/
/**
* Author: Cezar Andrei ( cezar.andrei at bea.com )
* Date: Apr 25, 2004
*/
package org.apache.xmlbeans.impl.config;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;
import java.util.Set;
import java.lang.reflect.Method;
/**
* This class reprezents all the extensions for all xbean sets.
* This class is the root of the structure that reprezents all the extensions.
*/
public class ExtensionHolder
{
// these lists are expected to be quite small
private List _interfaceExtensions;
private List _prePostExtensions;
ExtensionHolder()
{
_interfaceExtensions = new ArrayList();
_prePostExtensions = new ArrayList();
}
void addInterfaceExtension(InterfaceExtension ext)
{
if (ext==null)
return;
_interfaceExtensions.add(ext);
}
void addPrePostExtension(PrePostExtension ext)
{
if (ext==null)
return;
_prePostExtensions.add(ext);
}
// this is used only for detecting method colisions of extending interfaces
private static class MethodSignature
{
private String _intfName; // Stored only for error output, does not influence the equals or hashCode
private Method _method;
MethodSignature(String intfName, Method method)
{
if (intfName==null || method==null)
throw new IllegalArgumentException("Interface: " + intfName + " method: " + method);
_intfName = intfName;
_method = method;
}
String getInterfaceName()
{
return _intfName;
}
String getSignature()
{
String sig = "";
Class[] paramTypes = _method.getParameterTypes();
for (int i = 0; i < paramTypes.length; i++)
{
Class paramType = paramTypes[i];
sig += ( i==0 ? "" : " ," ) + paramType.getName();
}
return _method.getName() + "(" + sig + ")";
}
public boolean equals(Object o)
{
if ( !(o instanceof MethodSignature))
return false;
MethodSignature ms = (MethodSignature)o;
if (!ms._method.getName().equals(_method.getName()) )
return false;
Class[] paramTypes = _method.getParameterTypes();
Class[] msParamTypes = _method.getParameterTypes();
if (msParamTypes.length != paramTypes.length )
return false;
for (int i = 0; i < paramTypes.length; i++)
{
if (msParamTypes[i] != paramTypes[i])
return false;
}
return true;
}
public int hashCode()
{
int hash = _method.getName().hashCode();
Class[] paramTypes = _method.getParameterTypes();
for (int i = 0; i < paramTypes.length; i++)
{
hash *= 19;
hash += paramTypes[i].hashCode();
}
return hash;
}
}
void secondPhaseValidation()
{
// validate interface methods collisions
Map methodSignatures = new HashMap();
for (int i = 0; i < _interfaceExtensions.size(); i++)
{
InterfaceExtension interfaceExtension = (InterfaceExtension) _interfaceExtensions.get(i);
for (int j = 0; j < interfaceExtension.getInterfaceMethodCount(); j++)
{
MethodSignature ms = new MethodSignature(interfaceExtension.getInterfaceName(),
interfaceExtension.getInterfaceMethod(j));
if ( methodSignatures.containsKey(ms) )
{
MethodSignature ms2 = (MethodSignature) methodSignatures.get(ms);
SchemaConfig.error("Colliding methods '" + ms.getSignature() + "' in interfaces " +
ms.getInterfaceName() + " and " + ms2.getInterfaceName() + ".", null);
return;
}
// store it into hashmap
methodSignatures.put(ms, ms);
}
}
// validate that PrePostExtension-s do not intersect
for (int i = 0; i < _prePostExtensions.size() - 1; i++)
{
PrePostExtension a = (PrePostExtension) _prePostExtensions.get(i);
for (int j = 1; j < _prePostExtensions.size(); j++)
{
PrePostExtension b = (PrePostExtension) _prePostExtensions.get(j);
if (a.hasNameSetIntersection(b))
SchemaConfig.error("The applicable domain for handler '" + a.getHandlerNameForJavaSource() +
"' intersects with the one for '" + b.getHandlerNameForJavaSource() + "'.", null);
}
}
}
void normalize()
{
//todo: not yet used, useful for optimizing jar size in case of big interfaces and big schemas
throw new RuntimeException("NYI");
// this matters only for InterfaceExtension-s
}
public void verifyInterfaceNameCollisions(Set genedUsedNames)
{
for (int i = 0; i < _interfaceExtensions.size(); i++)
{
InterfaceExtension interfaceExtension = (InterfaceExtension) _interfaceExtensions.get(i);
if ( genedUsedNames.contains(interfaceExtension.getInterfaceNameForJavaSource().toLowerCase()) )
{
SchemaConfig.error("Extension interface '" + interfaceExtension.getInterfaceNameForJavaSource() + "' creates a name collision with one of the generated interfaces or classes.", null);
}
String handlerClassName = interfaceExtension.getHandlerNameForJavaSource();
if ( handlerClassName!=null &&
genedUsedNames.contains(handlerClassName.toLowerCase()) )
{
SchemaConfig.error("Handler class '" + handlerClassName + "' creates a name collision with one of the generated interfaces or classes.", null);
}
}
for (int i = 0; i < _prePostExtensions.size(); i++)
{
PrePostExtension prePostExtension = (PrePostExtension) _prePostExtensions.get(i);
String handlerClassName = prePostExtension.getHandlerNameForJavaSource();
if ( handlerClassName!=null &&
genedUsedNames.contains(handlerClassName.toLowerCase()) )
{
SchemaConfig.error("Handler class '" + prePostExtension.getHandlerNameForJavaSource() + "' creates a name collision with one of the generated interfaces or classes.", null);
}
}
}
ExtensionHolder extensionHolderFor(String javaName)
{
for (int i = 0; i < _interfaceExtensions.size(); i++)
{
InterfaceExtension interfaceExtension = (InterfaceExtension) _interfaceExtensions.get(i);
if (interfaceExtension.contains(javaName))
return this;
}
for (int i = 0; i < _prePostExtensions.size(); i++)
{
PrePostExtension prePostExtension = (PrePostExtension) _prePostExtensions.get(i);
if (prePostExtension.contains(javaName))
return this;
}
return null;
}
public List getInterfaceExtensionsFor(String fullJavaName)
{
List result = new ArrayList();
for (int i = 0; i < _interfaceExtensions.size(); i++)
{
InterfaceExtension intfExt = (InterfaceExtension) _interfaceExtensions.get(i);
if (intfExt.contains(fullJavaName))
result.add(intfExt);
}
return result;
}
public PrePostExtension getPrePostExtensionsFor(String fullJavaName)
{
for (int i = 0; i < _prePostExtensions.size(); i++)
{
PrePostExtension prePostExt = (PrePostExtension) _prePostExtensions.get(i);
if (prePostExt.contains(fullJavaName))
return prePostExt;
}
return null;
}
}