001: /*
002: * Copyright (c) 2001-2007, Jean Tessier
003: * All rights reserved.
004: *
005: * Redistribution and use in source and binary forms, with or without
006: * modification, are permitted provided that the following conditions
007: * are met:
008: *
009: * * Redistributions of source code must retain the above copyright
010: * notice, this list of conditions and the following disclaimer.
011: *
012: * * Redistributions in binary form must reproduce the above copyright
013: * notice, this list of conditions and the following disclaimer in the
014: * documentation and/or other materials provided with the distribution.
015: *
016: * * Neither the name of Jean Tessier nor the names of his contributors
017: * may be used to endorse or promote products derived from this software
018: * without specific prior written permission.
019: *
020: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
021: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
022: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
023: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
024: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
025: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
026: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
027: * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
028: * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
029: * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
030: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
031: */
032:
033: package com.jeantessier.diff;
034:
035: import java.util.*;
036:
037: import com.jeantessier.classreader.*;
038:
039: /**
040: * TODO class comments
041: */
042: public class IncompatibleDifferenceStrategy extends
043: APIDifferenceStrategy {
044: public IncompatibleDifferenceStrategy(DifferenceStrategy strategy) {
045: super (strategy);
046: }
047:
048: public boolean isClassDifferent(Classfile oldClass,
049: Classfile newClass) {
050: return isRemoved(oldClass, newClass)
051: || (!isNew(oldClass, newClass) && isClassModified(
052: oldClass, newClass));
053: }
054:
055: public boolean isFieldDifferent(Field_info oldField,
056: Field_info newField) {
057: return isRemoved(oldField, newField)
058: || isDeprecationModified(oldField, newField)
059: || isDeclarationModified(oldField, newField);
060: }
061:
062: public boolean isMethodDifferent(Method_info oldMethod,
063: Method_info newMethod) {
064: return isRemoved(oldMethod, newMethod)
065: || isDeprecationModified(oldMethod, newMethod)
066: || isDeclarationModified(oldMethod, newMethod);
067: }
068:
069: public boolean isPackageDifferent(Map oldPackage, Map newPackage) {
070: return isPackageRemoved(oldPackage, newPackage)
071: || (!isPackageNew(oldPackage, newPackage) && isPackageModified(
072: oldPackage, newPackage));
073: }
074:
075: public boolean isDeclarationModified(Classfile oldClass,
076: Classfile newClass) {
077: boolean result = false;
078:
079: result = oldClass != null
080: && newClass != null
081: && ((oldClass.isPublic() && !newClass.isPublic())
082: || (oldClass.isInterface() != newClass
083: .isInterface())
084: || (!oldClass.isAbstract() && newClass
085: .isAbstract())
086: || (!oldClass.isFinal() && newClass.isFinal())
087: || isExtendsClauseModified(oldClass, newClass) || isImplementsClauseModified(
088: oldClass, newClass));
089:
090: return result;
091: }
092:
093: private boolean isExtendsClauseModified(Classfile oldClass,
094: Classfile newClass) {
095: return !oldClass.getSuperclassName().equals(
096: newClass.getSuperclassName());
097: }
098:
099: private boolean isImplementsClauseModified(Classfile oldClass,
100: Classfile newClass) {
101: return !oldClass.getAllInterfaces().containsAll(
102: newClass.getAllInterfaces())
103: || !newClass.getAllInterfaces().containsAll(
104: oldClass.getAllInterfaces());
105: }
106:
107: private boolean isDeclarationModified(Field_info oldField,
108: Field_info newField) {
109: return oldField != null
110: && newField != null
111: && ((oldField.isPublic() && !newField.isPublic())
112: || (oldField.isProtected() && (newField
113: .isPackage() || newField.isPrivate()))
114: || (!oldField.isFinal() && newField.isFinal()) || !oldField
115: .getType().equals(newField.getType()));
116: }
117:
118: private boolean isDeclarationModified(Method_info oldMethod,
119: Method_info newMethod) {
120: return oldMethod != null
121: && newMethod != null
122: && ((oldMethod.isPublic() && !newMethod.isPublic())
123: || (oldMethod.isProtected() && (newMethod
124: .isPackage() || newMethod.isPrivate()))
125: || (!oldMethod.isAbstract() && newMethod
126: .isAbstract())
127: || (!oldMethod.isStatic() && newMethod
128: .isStatic())
129: || (!oldMethod.isFinal() && newMethod.isFinal())
130: || !oldMethod.getReturnType().equals(
131: newMethod.getReturnType()) || isThrowsClauseModified(
132: oldMethod, newMethod));
133: }
134:
135: private boolean isThrowsClauseModified(Method_info oldMethod,
136: Method_info newMethod) {
137: return !oldMethod.getExceptions().containsAll(
138: newMethod.getExceptions())
139: || !newMethod.getExceptions().containsAll(
140: oldMethod.getExceptions());
141: }
142:
143: protected boolean isDeprecationModified(Deprecatable oldItem,
144: Deprecatable newItem) {
145: return oldItem != null && newItem != null
146: && !oldItem.isDeprecated() && newItem.isDeprecated();
147: }
148: }
|