001 /**
002 * Copyright 2005-2012 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016 package org.kuali.rice.krms.impl;
017
018
019 import org.kuali.rice.core.api.criteria.CriteriaValue;
020 import org.kuali.rice.core.api.criteria.LookupCustomizer;
021 import org.kuali.rice.core.api.criteria.MultiValuedPredicate;
022 import org.kuali.rice.core.api.criteria.Predicate;
023 import org.kuali.rice.core.api.criteria.PropertyPathPredicate;
024 import org.kuali.rice.core.api.criteria.SingleValuedPredicate;
025
026 import java.util.ArrayList;
027 import java.util.List;
028 import java.util.Set;
029 import java.util.regex.Matcher;
030 import java.util.regex.Pattern;
031
032 import static org.kuali.rice.core.api.criteria.PredicateFactory.*;
033
034 /**
035 * this is an internal class used by krms (copied from kim) service implementations that have generic lookup methods for classes
036 * with "attributes".
037 */
038 public final class AttributeTransform implements LookupCustomizer.Transform<Predicate, Predicate> {
039
040 private static final LookupCustomizer.Transform<Predicate, Predicate> INSTANCE = new AttributeTransform();
041 private static final String ATTRIBUTE_DETAILS_ATTRIBUTE_VALUE = "attributeDetails.attributeValue";
042 private static final String ATTRIBUTE_DETAILS_ATTRIBUTE_NAME = "attributeDetails.krmsAttribute.attributeName";
043 private static final String ATTRIBUTES_REGEX = "^attributes\\[\\w*\\]$";
044 private static final Pattern ATTRIBUTES_PATTERN = Pattern.compile(ATTRIBUTES_REGEX);
045
046 private AttributeTransform() {
047
048 }
049
050 @Override
051 public Predicate apply(final Predicate input) {
052 if (input instanceof PropertyPathPredicate) {
053 String pp = ((PropertyPathPredicate) input).getPropertyPath();
054 if (isAttributesPredicate(pp)) {
055 final String attributeName = pp.substring(pp.indexOf('[') + 1, pp.indexOf(']'));
056
057 final Predicate attrValue;
058 if (input instanceof SingleValuedPredicate) {
059 final CriteriaValue<?> value = ((SingleValuedPredicate) input).getValue();
060 attrValue = dynConstruct(input.getClass().getSimpleName(), ATTRIBUTE_DETAILS_ATTRIBUTE_VALUE, value.getValue());
061 } else if (input instanceof MultiValuedPredicate) {
062 final Set<? extends CriteriaValue<?>> values = ((MultiValuedPredicate) input).getValues();
063 List<Object> l = new ArrayList<Object>();
064 for (CriteriaValue<?> v : values) {
065 l.add(v.getValue());
066 }
067
068 attrValue = dynConstruct(input.getClass().getSimpleName(), ATTRIBUTE_DETAILS_ATTRIBUTE_VALUE, l.toArray());
069 } else {
070 attrValue = dynConstruct(input.getClass().getSimpleName(), ATTRIBUTE_DETAILS_ATTRIBUTE_VALUE);
071 }
072 return and(equal(ATTRIBUTE_DETAILS_ATTRIBUTE_NAME, attributeName), attrValue);
073 }
074 }
075
076 return input;
077 }
078
079 private boolean isAttributesPredicate(String pp) {
080 Matcher matcher = ATTRIBUTES_PATTERN.matcher(pp);
081 return matcher.matches();
082 }
083
084 public static LookupCustomizer.Transform<Predicate, Predicate> getInstance() {
085 return INSTANCE;
086 }
087 }