blob: 59a70b5122b0b4b534a760c0e1502dc5771730e4 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*/
package org.apache.unomi.plugins.baseplugin.conditions;
import org.apache.unomi.api.*;
import org.apache.unomi.api.campaigns.Campaign;
import org.apache.unomi.api.goals.Goal;
import org.apache.unomi.api.rules.Rule;
import org.apache.unomi.plugins.baseplugin.conditions.accessors.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.*;
/**
* This class contains the registry of all the hardcoded property accessors.
* For the moment this list of accessors is hardcoded, but in a future update it could be made dynamic.
*/
public class HardcodedPropertyAccessorRegistry {
private static final Logger logger = LoggerFactory.getLogger(HardcodedPropertyAccessorRegistry.class.getName());
Map<String, HardcodedPropertyAccessor> propertyAccessors = new HashMap<>();
public HardcodedPropertyAccessorRegistry() {
propertyAccessors.put(Item.class.getName(), new ItemAccessor(this));
propertyAccessors.put(MetadataItem.class.getName(), new MetadataItemAccessor(this));
propertyAccessors.put(Metadata.class.getName(), new MetadataAccessor(this));
propertyAccessors.put(TimestampedItem.class.getName(), new TimestampedItemAccessor(this));
propertyAccessors.put(Event.class.getName(), new EventAccessor(this));
propertyAccessors.put(Profile.class.getName(), new ProfileAccessor(this));
propertyAccessors.put(Consent.class.getName(), new ConsentAccessor(this));
propertyAccessors.put(Session.class.getName(), new SessionAccessor(this));
propertyAccessors.put(Rule.class.getName(), new RuleAccessor(this));
propertyAccessors.put(Goal.class.getName(), new GoalAccessor(this));
propertyAccessors.put(CustomItem.class.getName(), new CustomItemAccessor(this));
propertyAccessors.put(Campaign.class.getName(), new CampaignAccessor(this));
propertyAccessors.put(Map.class.getName(), new MapAccessor(this));
}
public static class NextTokens {
public String propertyName;
public String leftoverExpression;
}
protected NextTokens getNextTokens(String expression) {
if (expression.startsWith("[\"")) {
int lookupNameBeginPos = "[\"".length();
int lookupNameEndPos = expression.indexOf("\"]", lookupNameBeginPos);
return buildNextTokens(expression, lookupNameBeginPos, lookupNameEndPos, lookupNameEndPos+2);
} else if (expression.startsWith(".")) {
int lookupNameBeginPos = ".".length();
int lookupNameEndPos = findNextStartDelimiterPos(expression, lookupNameBeginPos);
return buildNextTokens(expression, lookupNameBeginPos, lookupNameEndPos, lookupNameEndPos);
} else {
int lookupNameBeginPos = 0;
int lookupNameEndPos = findNextStartDelimiterPos(expression, lookupNameBeginPos);
return buildNextTokens(expression, lookupNameBeginPos, lookupNameEndPos, lookupNameEndPos);
}
}
private NextTokens buildNextTokens(String expression, int lookupNameBeginPos, int lookupNameEndPos, int leftoverStartPos) {
NextTokens nextTokens = new NextTokens();
if (lookupNameEndPos >= lookupNameBeginPos) {
nextTokens.propertyName = expression.substring(lookupNameBeginPos, lookupNameEndPos);
nextTokens.leftoverExpression = expression.substring(leftoverStartPos);
if ("".equals(nextTokens.leftoverExpression)) {
nextTokens.leftoverExpression = null;
}
} else {
nextTokens.propertyName = expression.substring(lookupNameBeginPos);
nextTokens.leftoverExpression = null;
}
return nextTokens;
}
private int findNextStartDelimiterPos(String expression, int lookupNameBeginPos) {
int lookupNameEndPos;
int dotlookupNameEndPos = expression.indexOf(".", lookupNameBeginPos);
int squareBracketlookupNameEndPos = expression.indexOf("[\"", lookupNameBeginPos);
if (dotlookupNameEndPos >= lookupNameBeginPos && squareBracketlookupNameEndPos >= lookupNameBeginPos) {
lookupNameEndPos = Math.min(dotlookupNameEndPos, squareBracketlookupNameEndPos);
} else if (dotlookupNameEndPos >= lookupNameBeginPos) {
lookupNameEndPos = dotlookupNameEndPos;
} else if (squareBracketlookupNameEndPos >= lookupNameBeginPos) {
lookupNameEndPos = squareBracketlookupNameEndPos;
} else {
lookupNameEndPos = -1;
}
return lookupNameEndPos;
}
public Object getProperty(Object object, String expression) {
if (expression == null) {
return object;
}
if (expression.trim().equals("")) {
return object;
}
NextTokens nextTokens = getNextTokens(expression);
List<Class<?>> lookupClasses = new ArrayList<>();
lookupClasses.add(object.getClass());
lookupClasses.add(object.getClass().getSuperclass());
lookupClasses.addAll(Arrays.asList(object.getClass().getInterfaces()));
for (Class<?> lookupClass : lookupClasses) {
HardcodedPropertyAccessor propertyAccessor = propertyAccessors.get(lookupClass.getName());
if (propertyAccessor != null) {
Object result = propertyAccessor.getProperty(object, nextTokens.propertyName, nextTokens.leftoverExpression);
if (!HardcodedPropertyAccessor.PROPERTY_NOT_FOUND_MARKER.equals(result)) {
return result;
}
}
}
logger.warn("Couldn't find any property access for class {} and expression {}", object.getClass().getName(), expression);
return HardcodedPropertyAccessor.PROPERTY_NOT_FOUND_MARKER;
}
}