/*
* � Copyright IBM Corp. 2013
*
* 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: Maire Kehoe (mkehoe@ie.ibm.com)
* Date: 31-Mar-2006
* KnownPropertyRedefinitionTest.java
*/
package com.ibm.xsp.test.framework.registry;
import java.util.ArrayList;
import java.util.List;
import com.ibm.commons.util.StringUtil;
import com.ibm.xsp.registry.FacesContainerProperty;
import com.ibm.xsp.registry.FacesDefinition;
import com.ibm.xsp.registry.FacesProperty;
import com.ibm.xsp.registry.FacesSharableRegistry;
import com.ibm.xsp.registry.FacesSimpleProperty;
import com.ibm.xsp.registry.RegistryUtil;
import com.ibm.xsp.test.framework.AbstractXspTest;
import com.ibm.xsp.test.framework.TestProject;
import com.ibm.xsp.test.framework.XspTestUtil;
import com.ibm.xsp.test.framework.setup.SkipFileContent;
/**
* @author Maire Kehoe (mkehoe@ie.ibm.com)
* 31-Mar-2006
* Unit: KnownPropertyRedefinitionTest.java
*/
public class KnownPropertyRedefinitionTest extends AbstractXspTest {
@Override
public String getDescription() {
return "that only the expected properties are redefined, " +
"to prevent accidentally redefining them.";
}
// namespace, definition id, property name, changes
private List<String[]> _knownChanges;
public void testKnownPropertyRedefinition() {
// this test is constrained by the fact that it can only check
// for one property per definition
FacesSharableRegistry reg = TestProject.createRegistry(this);
_knownChanges = getKnownChangesSkips();
// the method checkRedefinedProperty will be called for each
// redefined property when the getProperties method is called
String fails = "";
for (FacesDefinition def : TestProject.getLibDefinitions(reg, this)) {
FacesDefinition parent = def.getParent();
if( null == parent ){
continue;
}
for (String name : def.getDefinedPropertyNames()) {
FacesProperty originalProp = parent.getProperty(name);
if( null == originalProp ){
continue;
}
FacesProperty prop = def.getProperty(name);
fails += checkRedefinedProperty(def, prop, originalProp);
}
}
// check that all known changes were found (& deleted)
for (String[] nullOrKnownChange : _knownChanges) {
if( null != nullOrKnownChange ){
fails += "expected change not found: "
+ StringUtil.concatStrings(nullOrKnownChange, ',', true)+"\n";
}
}
fails = XspTestUtil.removeMultilineFailSkips(fails,
SkipFileContent.concatSkips(null, this, "testKnownPropertyRedefinition"));
if( fails.length() > 0 ){
fail(XspTestUtil.getMultilineFailMessage(fails));
}
}
protected List<String[]> getKnownChangesSkips() {
return new ArrayList<String[]>();
}
private String checkRedefinedProperty(FacesDefinition def,
FacesProperty prop, FacesProperty originalProp) {
// the changed value(s) in the redefined property
String changes = getChanges(prop, originalProp);
String[] foundChanges = new String[] { def.getNamespaceUri(),
def.getId(), prop.getName(), changes };
// the index of the found changes in the array of known changes
int indexOfFoundInKnown = -1;
int i = 0;
for (String[] nullOrKnownChange : _knownChanges) {
if( equals(foundChanges, nullOrKnownChange) ){
indexOfFoundInKnown = i;
break;
}
i++;
}
if (-1 == indexOfFoundInKnown) {
return def.getFile().getFilePath() + " " +RegistryUtil.getDefaultPrefix(def) + ":" + foundChanges[1]
+ "." + foundChanges[2] + " unexpectedly redefined. Change: "
+ foundChanges[3] + ".\n";
}
// else found the change, remove it from the search
_knownChanges.set(indexOfFoundInKnown, null);
return "";
}
/**
* @param prop
* @return
*/
public static String getChanges(FacesProperty prop, FacesProperty originalProp) {
// isResource, isLocalizable, isRequired
String changes = "";
if( prop.isRequired() != originalProp.isRequired() ){
changes = "required="+Boolean.toString(prop.isRequired());
}
if( prop instanceof FacesContainerProperty){
FacesContainerProperty propContain = (FacesContainerProperty)prop;
boolean isOriginalContainer = originalProp instanceof FacesContainerProperty;
FacesContainerProperty origContain = isOriginalContainer? (FacesContainerProperty)originalProp : null;
if (propContain.isArray() != (isOriginalContainer ? origContain.isArray()
: false )) {
changes += comma(changes) + "array-property="
+ Boolean.valueOf(propContain.isArray());
}
if (propContain.isCollection() != (isOriginalContainer ? origContain.isCollection()
: false )) {
changes += comma(changes) + "collection-property="
+ Boolean.valueOf(propContain.isCollection());
}
if (propContain.isMap() != (isOriginalContainer ? origContain.isMap()
: false )) {
changes += comma(changes) + "map-property="
+ Boolean.valueOf(propContain.isMap());
}
prop = propContain.getItemProperty();
if( isOriginalContainer ){
originalProp = origContain.getItemProperty();
}
}
if( prop.getJavaClass() != originalProp.getJavaClass() ){
changes += comma(changes)
+ "java-class="
+ prop.getJavaClass().getName();
}
if( prop instanceof FacesSimpleProperty ){
FacesSimpleProperty oldFoo = (FacesSimpleProperty)originalProp;
FacesSimpleProperty newFoo = (FacesSimpleProperty)prop;
if( newFoo.isLocalizable() != oldFoo.isLocalizable() ){
changes += comma(changes)
+ "localizable="
+ Boolean.valueOf(newFoo.isLocalizable()).toString();
}
if( !StringUtil.equals(newFoo.getSince(), oldFoo.getSince()) ){
changes += comma(changes)
+ "since="
+ newFoo.getSince();
}
if( newFoo.isAllowRunTimeBinding() != oldFoo.isAllowRunTimeBinding() ){
changes += comma(changes)
+ "allow-run-time-binding="
+ Boolean.valueOf(newFoo.isAllowRunTimeBinding()).toString();
}
if( newFoo.isAllowLoadTimeBinding() != oldFoo.isAllowLoadTimeBinding() ){
changes += comma(changes)
+ "allow-load-time-binding="
+ Boolean.valueOf(newFoo.isAllowLoadTimeBinding()).toString();
}
if( newFoo.isAllowNonBinding() != oldFoo.isAllowNonBinding() ){
changes += comma(changes)
+ "allow-non-binding="
+ Boolean.valueOf(newFoo.isAllowNonBinding()).toString();
}
}
if( changes.length() == 0 ){
changes = "none";
}
return changes;
}
public static String comma(String str) {
return str.length() == 0 ? "": ",";
}
/**
* @param foundChange
* @param nullOrKnownChange
* @return
*/
private boolean equals(String[] foundChange, String[] nullOrKnownChange) {
if( null == nullOrKnownChange ){
return false;
}
for (int i = 0; i < foundChange.length; i++) {
if( !foundChange[i].equals(nullOrKnownChange[i])){
return false;
}
}
return true;
}
}