blob: ec183b8b2b91b3cbba8601bc5cc2ef10b4dd6cfd [file] [log] [blame]
/*
* Copyright 2010 Google Inc.
*
* 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.
*/
package com.google.gwt.requestfactory.server;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
/**
* <p> <span style="color:red">Experimental API: This class is still under rapid development, and is
* very likely to be deleted. Use it at your own risk. </span> </p> Represents one piece in a
* property reference sequence.
*/
public class RequestProperty implements Iterable<RequestProperty> {
/**
* Merge two property chains.
*/
public static RequestProperty coalesce(RequestProperty... properties) {
assert properties.length > 0;
RequestProperty root = new RequestProperty("");
for (RequestProperty prop : properties) {
if ("".equals(prop.getPropertyName())) {
for (RequestProperty p : prop) {
root.mergeProperty(p);
}
} else {
root.mergeProperty(prop);
}
}
return root;
}
public static RequestProperty parse(String selectors) {
String parts[] = selectors.split("\\s*,\\s*");
RequestProperty props[] = new RequestProperty[parts.length];
for (int i = 0; i < parts.length; i++) {
RequestProperty newProp = new RequestProperty("");
newProp.parseInternal(parts[i]);
props[i] = newProp;
}
return props.length == 1 ? props[0] : coalesce(props);
}
private String propertyName;
private Map<String, RequestProperty> subProperties;
private RequestProperty(String propertyName) {
this.propertyName = propertyName;
}
public RequestProperty add(RequestProperty propertyRef) {
if (subProperties == null) {
subProperties = new HashMap<String, RequestProperty>();
}
subProperties.put(propertyRef.getPropertyName(), propertyRef);
return this;
}
public RequestProperty getProperty(String propName) {
return subProperties == null ? null : subProperties.get(propName);
}
public String getPropertyName() {
return propertyName;
}
public boolean hasProperty(String name) {
return subProperties == null ? false : subProperties.containsKey(name);
}
public Iterator<RequestProperty> iterator() {
return subProperties == null ? emptyIterator()
: subProperties.values().iterator();
}
public RequestProperty mergeProperty(RequestProperty property) {
RequestProperty foundProp = getProperty(property.getPropertyName());
if (foundProp == null && !"".equals(property.getPropertyName())) {
add(property);
} else {
for (RequestProperty p : property) {
if (foundProp == null) {
add(p);
} else {
foundProp.mergeProperty(p);
}
}
}
return foundProp;
}
@SuppressWarnings({"cast", "unchecked"})
private Iterator<RequestProperty> emptyIterator() {
return (Iterator<RequestProperty>) Collections.EMPTY_MAP.values().iterator();
}
private RequestProperty getOrCreate(String part) {
RequestProperty prop = getProperty(part);
if (prop == null) {
prop = new RequestProperty(part);
add(prop);
}
return prop;
}
private RequestProperty parseInternal(String sequence) {
int dotIndex = sequence.indexOf('.');
String part = dotIndex > -1 ? sequence.substring(0, dotIndex) : sequence;
RequestProperty prop = getOrCreate(part);
add(prop);
if (dotIndex > -1) {
if (dotIndex < sequence.length() - 1) {
String next = sequence.substring(dotIndex + 1);
if ("".equals(next)) {
throw new IllegalArgumentException("Empty property name '..' not allowed in " + sequence);
}
if (next.length() > 0) {
return prop.parseInternal(next);
}
}
throw new IllegalArgumentException("Trailing '.' in with() call " + sequence);
}
return prop;
}
}