Skip to content

Commit

Permalink
Merge branch 'master' into closure
Browse files Browse the repository at this point in the history
  • Loading branch information
mederly committed Oct 15, 2014
2 parents a385214 + 3a58995 commit 38d7655
Show file tree
Hide file tree
Showing 54 changed files with 1,623 additions and 238 deletions.
Expand Up @@ -667,7 +667,7 @@ private ObjectDelta createAddingObjectDelta() throws SchemaException {
Collections.sort(containers, new ItemWrapperComparator());

if (InternalsConfig.consistencyChecks) {
delta.checkConsistence(true, true, true);
delta.checkConsistence(true, true, true, ConsistencyCheckScope.THOROUGH);
}

return delta;
Expand Down
Expand Up @@ -24,6 +24,8 @@
import com.evolveum.midpoint.prism.xjc.AnyArrayList;
import com.evolveum.midpoint.prism.xml.XsdTypeMapper;
import com.evolveum.midpoint.schema.constants.SchemaConstants;
import com.evolveum.midpoint.schema.processor.ResourceAttribute;
import com.evolveum.midpoint.schema.util.ShadowUtil;
import com.evolveum.midpoint.util.DOMUtil;
import com.evolveum.midpoint.web.component.input.*;
import com.evolveum.midpoint.web.component.util.VisibleEnableBehaviour;
Expand All @@ -33,9 +35,9 @@
import com.evolveum.midpoint.xml.ns._public.common.common_3.*;
import com.evolveum.midpoint.xml.ns.model.workflow.common_forms_3.RoleApprovalFormType;
import com.evolveum.prism.xml.ns._public.types_3.ProtectedStringType;

import com.sun.org.apache.xerces.internal.dom.ElementNSImpl;
import com.sun.org.apache.xerces.internal.dom.TextImpl;

import org.apache.commons.lang.ClassUtils;
import org.apache.commons.lang.Validate;
import org.apache.wicket.AttributeModifier;
Expand All @@ -57,6 +59,7 @@
import javax.xml.namespace.QName;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
Expand Down Expand Up @@ -436,22 +439,51 @@ private String createAssociationTooltipText(PrismProperty property){
PrismObject<ShadowType> shadowPrism = (PrismObject<ShadowType>)property.getParent().getParent();
ShadowType shadow = shadowPrism.asObjectable();

if(shadow.getAttributes() != null){
ShadowAttributesType attributes = shadow.getAttributes();
AnyArrayList attrs = (AnyArrayList)attributes.getAny();

for(Object o: attrs){
ElementNSImpl element = (ElementNSImpl)o;
sb.append(element.getLocalName() + ": ");
sb.append(((TextImpl)element.getFirstChild()).getData() + "<br>");
}
Collection<ResourceAttribute<?>> attributes = ShadowUtil.getAttributes(shadowPrism);
if (attributes == null || attributes.isEmpty()){
return sb.toString();
}

for (ResourceAttribute<?> attr : attributes){
for (Object realValue : attr.getRealValues()){
sb.append(getAttributeName(attr));
sb.append(":");
sb.append(realValue);
sb.append("<br>");
}
}
// if(shadow.getAttributes() != null){
// ShadowAttributesType attributes = shadow.getAttributes();
// AnyArrayList attrs = (AnyArrayList)attributes.getAny();
//
// for(Object o: attrs){
// ElementNSImpl element = (ElementNSImpl)o;
// sb.append(element.getLocalName() + ": ");
// sb.append(((TextImpl)element.getFirstChild()).getData() + "<br>");
// }
// }
}

return sb.toString();
}

private void addValue(AjaxRequestTarget target) {
private String getAttributeName(ResourceAttribute<?> attr) {
if (attr.getDisplayName() != null){
return attr.getDisplayName();
}

if (attr.getNativeAttributeName() != null){
return attr.getNativeAttributeName();
}

if (attr.getElementName() != null){
return attr.getElementName().getLocalPart();
}

return null; //TODO: is this ok?? or better is exception or some default name??
}

private void addValue(AjaxRequestTarget target) {
ValueWrapper wrapper = model.getObject();
PropertyWrapper propertyWrapper = wrapper.getProperty();
propertyWrapper.addValue();
Expand Down
Expand Up @@ -581,7 +581,7 @@ private void reconcilePerformed(AjaxRequestTarget target, UserListItemDto select
ObjectDelta delta = ObjectDelta.createEmptyModifyDelta(UserType.class, user.getOid(), getPrismContext());
Collection<ObjectDelta<? extends ObjectType>> deltas = WebMiscUtil.createDeltaCollection(delta);
getModelService().executeChanges(deltas, ModelExecuteOptions.createReconcile(), task, opResult);
opResult.recordSuccess();
opResult.computeStatusIfUnknown();
} catch (Exception ex) {
opResult.recomputeStatus();
opResult.recordFatalError("Couldn't reconcile user " + userShortString + ".", ex);
Expand Down
Expand Up @@ -23,6 +23,7 @@
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
Expand Down Expand Up @@ -458,8 +459,8 @@ private synchronized <T extends DummyObject> String addObject(Map<String,T> map,

//this is "resource-generated" attribute (used to simulate resource which generate by default attributes which we need to sync)
if (generateDefaultValues){
int internalId = allObjects.size();
newObject.addAttributeValue(DummyAccount.ATTR_INTERNAL_ID, internalId++);
// int internalId = allObjects.size();
newObject.addAttributeValue(DummyAccount.ATTR_INTERNAL_ID, new Random().nextInt());
}


Expand Down
Expand Up @@ -31,6 +31,7 @@
import javax.xml.bind.JAXBException;
import javax.xml.namespace.QName;

import com.evolveum.midpoint.prism.ConsistencyCheckScope;
import com.evolveum.midpoint.prism.util.PrismTestUtil;

import org.testng.Assert;
Expand Down Expand Up @@ -356,7 +357,7 @@ private void assertAccountShadow(PrismObject<ShadowType> accObject, PrismObject<
String accString = PrismTestUtil.serializeObjectToString(accObjectType.asPrismObject());
System.out.println("Result of JAXB marshalling:\n"+accString);

accObject.checkConsistence(true, true);
accObject.checkConsistence(true, true, ConsistencyCheckScope.THOROUGH);
}

private QName getAttrQName(PrismObject<ResourceType> resource, String localPart) {
Expand Down
@@ -0,0 +1,40 @@
package com.evolveum.midpoint.prism;

import com.evolveum.midpoint.prism.delta.ObjectDelta;

import java.util.Collection;

/**
* Determines the scope of consistency checks.
*
* (Originally this was a boolean, but there are many 'checkConsistence'-style methods with a set of boolean arguments,
* so it was too easy to mix them up with this new one.)
*
* @author mederly
*/
public enum ConsistencyCheckScope {
/**
* Full-scale checks.
*/
THOROUGH,
/**
* Mandatory checks, e.g. checks for duplicate container IDs (see MID-1951).
* Should be rather quick.
*
* TODO Current solution is not that optimal. We should distinguish between checks that deal with midPoint internal workings
* (throwing IllegalArgumentException/IllegalStateException on failure), which can be turned off, as it is today. Another set
* of checks should be applied only on users' inputs (when importing data, when accepting inputs via SOAP/REST/whathever interfaces, ...)
* - and these should throw perhaps SchemaException that can be caught and handled appropriately.
*
* However, for the time being we consider this approach (i.e. that both kinds of checks are implemented the same way) to be an acceptable one.
*/
MANDATORY_CHECKS_ONLY;

public boolean isThorough() {
return this == THOROUGH;
}

public static ConsistencyCheckScope fromBoolean(boolean consistencyChecksSwitchValue) {
return consistencyChecksSwitchValue ? THOROUGH : MANDATORY_CHECKS_ONLY;
}
}
27 changes: 17 additions & 10 deletions infra/prism/src/main/java/com/evolveum/midpoint/prism/Item.java
Expand Up @@ -25,8 +25,6 @@
import com.evolveum.midpoint.util.exception.SchemaException;
import com.evolveum.midpoint.util.exception.SystemException;

import org.w3c.dom.Element;

import javax.xml.namespace.QName;

import java.io.Serializable;
Expand Down Expand Up @@ -619,19 +617,28 @@ public static <T extends Item> T createNewDefinitionlessItem(QName name, Class<T
return item;
}

public void checkConsistence(boolean requireDefinitions) {
checkConsistenceInternal(this, requireDefinitions, false);
public void checkConsistence(boolean requireDefinitions, ConsistencyCheckScope scope) {
checkConsistenceInternal(this, requireDefinitions, false, scope);
}

public void checkConsistence(boolean requireDefinitions, boolean prohibitRaw) {
checkConsistenceInternal(this, requireDefinitions, prohibitRaw);
checkConsistenceInternal(this, requireDefinitions, prohibitRaw, ConsistencyCheckScope.THOROUGH);
}

public void checkConsistence(boolean requireDefinitions, boolean prohibitRaw, ConsistencyCheckScope scope) {
checkConsistenceInternal(this, requireDefinitions, prohibitRaw, scope);
}

public void checkConsistence() {
checkConsistenceInternal(this, false, false);
checkConsistenceInternal(this, false, false, ConsistencyCheckScope.THOROUGH);
}

public void checkConsistenceInternal(Itemable rootItem, boolean requireDefinitions, boolean prohibitRaw) {

public void checkConsistence(ConsistencyCheckScope scope) {
checkConsistenceInternal(this, false, false, scope);
}


public void checkConsistenceInternal(Itemable rootItem, boolean requireDefinitions, boolean prohibitRaw, ConsistencyCheckScope scope) {
ItemPath path = getPath();
if (elementName == null) {
throw new IllegalStateException("Item "+this+" has no name ("+path+" in "+rootItem+")");
Expand All @@ -657,7 +664,7 @@ public void checkConsistenceInternal(Itemable rootItem, boolean requireDefinitio
throw new IllegalStateException("Wrong parent for value "+val+" in item "+this+" ("+path+" in "+rootItem+"), "+
"bad parent: " + val.getParent());
}
val.checkConsistenceInternal(rootItem, requireDefinitions, prohibitRaw);
val.checkConsistenceInternal(rootItem, requireDefinitions, prohibitRaw, scope);
}
}
}
Expand Down
Expand Up @@ -168,6 +168,13 @@ public boolean add(PrismContainerValue newValue) throws SchemaException {
if (newValue.getPrismContext() == null && this.prismContext != null) {
prismContext.adopt(newValue);
}
if (newValue.getId() != null) {
for (PrismContainerValue existingValue : getValues()) {
if (existingValue.getId() != null && existingValue.getId().equals(newValue.getId())) {
throw new IllegalStateException("Attempt to add a container value with an id that already exists: " + newValue.getId());
}
}
}
return super.add(newValue);
}

Expand Down Expand Up @@ -615,17 +622,34 @@ protected void checkDefinition(ItemDefinition def) {

@Override
public void checkConsistenceInternal(Itemable rootItem, boolean requireDefinitions,
boolean prohibitRaw) {
// Containers that are from run-time schema cannot have compile-time class.
if (getDefinition() != null && !getDefinition().isRuntimeSchema()) {
if (getCompileTimeClass() == null) {
throw new IllegalStateException("No compile-time class in "+this+" ("+getPath()+" in "+rootItem+")");
}
}
super.checkConsistenceInternal(rootItem, requireDefinitions, prohibitRaw);
boolean prohibitRaw, ConsistencyCheckScope scope) {
checkIds();
if (scope.isThorough()) {
// Containers that are from run-time schema cannot have compile-time class.
if (getDefinition() != null && !getDefinition().isRuntimeSchema()) {
if (getCompileTimeClass() == null) {
throw new IllegalStateException("No compile-time class in "+this+" ("+getPath()+" in "+rootItem+")");
}
}
}
super.checkConsistenceInternal(rootItem, requireDefinitions, prohibitRaw, scope);
}

@Override
private void checkIds() {
Set<Long> oidsUsed = new HashSet<>();
for (PrismContainerValue value : getValues()) {
Long id = value.getId();
if (id != null) {
if (oidsUsed.contains(id)) {
throw new IllegalArgumentException("There are more container values with the id of " + id + " in " + getElementName());
} else {
oidsUsed.add(id);
}
}
}
}

@Override
public void assertDefinitions(boolean tolarateRaw, String sourceDescription) throws SchemaException {
super.assertDefinitions(tolarateRaw, sourceDescription);
for (PrismContainerValue<V> val: getValues()) {
Expand Down
Expand Up @@ -1256,31 +1256,35 @@ public void normalize() {
}

@Override
public void checkConsistenceInternal(Itemable rootItem, boolean requireDefinitions, boolean prohibitRaw) {
ItemPath myPath = getPath();
if (prohibitRaw && isRaw()) {
throw new IllegalStateException("Raw elements in container value "+this+" ("+myPath+" in "+rootItem+")");
}
if (items == null && !isRaw()) {
// This is normal empty container, isn't it?
// throw new IllegalStateException("Neither items nor raw elements specified in container value "+this+" ("+myPath+" in "+rootItem+")");
}
if (items != null && isRaw()) {
throw new IllegalStateException("Both items and raw elements specified in container value "+this+" ("+myPath+" in "+rootItem+")");
}
public void checkConsistenceInternal(Itemable rootItem, boolean requireDefinitions, boolean prohibitRaw, ConsistencyCheckScope scope) {
ItemPath myPath = getPath();
if (scope.isThorough()) {
if (prohibitRaw && isRaw()) {
throw new IllegalStateException("Raw elements in container value "+this+" ("+myPath+" in "+rootItem+")");
}
if (items == null && !isRaw()) {
// This is normal empty container, isn't it?
// throw new IllegalStateException("Neither items nor raw elements specified in container value "+this+" ("+myPath+" in "+rootItem+")");
}
if (items != null && isRaw()) {
throw new IllegalStateException("Both items and raw elements specified in container value "+this+" ("+myPath+" in "+rootItem+")");
}
}
if (items != null) {
for (Item<?> item: items) {
if (item == null) {
throw new IllegalStateException("Null item in container value "+this+" ("+myPath+" in "+rootItem+")");
}
if (item.getParent() == null) {
throw new IllegalStateException("No parent for item "+item+" in container value "+this+" ("+myPath+" in "+rootItem+")");
}
if (item.getParent() != this) {
throw new IllegalStateException("Wrong parent for item "+item+" in container value "+this+" ("+myPath+" in "+rootItem+"), " +
"bad parent: "+ item.getParent());
}
item.checkConsistenceInternal(rootItem, requireDefinitions, prohibitRaw);
if (scope.isThorough()) {
if (item == null) {
throw new IllegalStateException("Null item in container value "+this+" ("+myPath+" in "+rootItem+")");
}
if (item.getParent() == null) {
throw new IllegalStateException("No parent for item "+item+" in container value "+this+" ("+myPath+" in "+rootItem+")");
}
if (item.getParent() != this) {
throw new IllegalStateException("Wrong parent for item "+item+" in container value "+this+" ("+myPath+" in "+rootItem+"), " +
"bad parent: "+ item.getParent());
}
}
item.checkConsistenceInternal(rootItem, requireDefinitions, prohibitRaw, scope);
}
}
}
Expand Down
Expand Up @@ -249,7 +249,11 @@ void checkValue() {
}

@Override
public void checkConsistenceInternal(Itemable rootItem, boolean requireDefinitions, boolean prohibitRaw) {
public void checkConsistenceInternal(Itemable rootItem, boolean requireDefinitions, boolean prohibitRaw, ConsistencyCheckScope scope) {
if (!scope.isThorough()) {
return;
}

ItemPath myPath = getPath();
if (prohibitRaw && rawElement != null) {
throw new IllegalStateException("Raw element in property value "+this+" ("+myPath+" in "+rootItem+")");
Expand Down
Expand Up @@ -248,7 +248,11 @@ public void recompute(PrismContext prismContext) {
}

@Override
public void checkConsistenceInternal(Itemable rootItem, boolean requireDefinitions, boolean prohibitRaw) {
public void checkConsistenceInternal(Itemable rootItem, boolean requireDefinitions, boolean prohibitRaw, ConsistencyCheckScope scope) {
if (!scope.isThorough()) {
return;
}

ItemPath myPath = getPath();

if (oid == null && object == null && filter == null) {
Expand Down
Expand Up @@ -163,7 +163,7 @@ public void accept(Visitor visitor, ItemPath path, boolean recursive) {
}
}

public abstract void checkConsistenceInternal(Itemable rootItem, boolean requireDefinitions, boolean prohibitRaw);
public abstract void checkConsistenceInternal(Itemable rootItem, boolean requireDefinitions, boolean prohibitRaw, ConsistencyCheckScope scope);

/**
* Returns true if this and other value represent the same value.
Expand Down

0 comments on commit 38d7655

Please sign in to comment.