blob: b7b646d96dbaf40020e81c5813aa9be1f005372c [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.olingo.odata2.core.uri;
import java.io.IOException;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.olingo.odata2.api.edm.EdmEntitySet;
import org.apache.olingo.odata2.api.edm.EdmEntityType;
import org.apache.olingo.odata2.api.edm.EdmException;
import org.apache.olingo.odata2.api.edm.EdmNavigationProperty;
import org.apache.olingo.odata2.api.edm.EdmProperty;
import org.apache.olingo.odata2.api.edm.EdmTyped;
import org.apache.olingo.odata2.api.uri.ExpandSelectTreeNode;
import org.apache.olingo.odata2.core.ep.util.JsonStreamWriter;
import org.apache.olingo.odata2.core.exception.ODataRuntimeException;
/**
*
*/
public class ExpandSelectTreeNodeImpl extends ExpandSelectTreeNode {
public enum AllKinds {
IMPLICITLYTRUE(true), EXPLICITLYTRUE(true), FALSE(false);
private boolean booleanRepresentation;
private AllKinds(final boolean booleanRepresentation) {
this.booleanRepresentation = booleanRepresentation;
}
public boolean getBoolean() {
return booleanRepresentation;
}
}
private AllKinds isAll = AllKinds.IMPLICITLYTRUE;
private boolean isExplicitlySelected = false;
private boolean isExpanded = false;
private final List<EdmProperty> properties = new ArrayList<EdmProperty>();
private final Map<String, ExpandSelectTreeNodeImpl> links = new HashMap<String, ExpandSelectTreeNodeImpl>();
private final List<ExpandSelectTreeNode> expandselectTreeNodes = new ArrayList<ExpandSelectTreeNode>();
@Override
public boolean isAll() {
return isAll.getBoolean();
}
@Override
public List<EdmProperty> getProperties() {
return properties;
}
@SuppressWarnings("unchecked")
@Override
public Map<String, ExpandSelectTreeNode> getLinks() {
return (Map<String, ExpandSelectTreeNode>) ((Map<String, ? extends ExpandSelectTreeNode>) Collections
.unmodifiableMap(links));
}
@Override
public List<ExpandSelectTreeNode> getExpandedList() {
return expandselectTreeNodes;
}
public void putLink(final String name, final ExpandSelectTreeNodeImpl node) {
links.put(name, node);
}
public void removeLink(final String name) {
links.remove(name);
}
public boolean isExplicitlySelected() {
return isExplicitlySelected;
}
public void setExplicitlySelected() {
isExplicitlySelected = true;
setAllExplicitly();
}
public boolean isExpanded() {
return isExpanded;
}
public void setExpanded() {
isExpanded = true;
}
public void addProperty(final EdmProperty property) {
if (property != null && isAll != AllKinds.EXPLICITLYTRUE && !properties.contains(property)) {
properties.add(property);
isAll = AllKinds.FALSE;
}
}
public void setAllExplicitly() {
properties.clear();
isAll = AllKinds.EXPLICITLYTRUE;
}
public AllKinds getAllKind() {
return isAll;
}
public void setAllKindFalse() {
isAll = AllKinds.FALSE;
}
public String toJsonString() {
try {
StringWriter writer = new StringWriter();
JsonStreamWriter jsonStreamWriter = new JsonStreamWriter(writer);
jsonStreamWriter.beginObject()
.name("all").unquotedValue(Boolean.toString(isAll())).separator()
.name("properties")
.beginArray();
boolean first = true;
for (EdmProperty property : properties) {
if (first) {
first = false;
} else {
jsonStreamWriter.separator();
}
jsonStreamWriter.stringValueRaw(property.getName());
}
jsonStreamWriter.endArray().separator()
.name("links")
.beginArray();
first = true;
for (Map.Entry<String, ExpandSelectTreeNodeImpl> entry : links.entrySet()) {
if (first) {
first = false;
} else {
jsonStreamWriter.separator();
}
final String nodeString = entry.getValue() == null ? null : entry.getValue().toJsonString();
jsonStreamWriter.beginObject()
.name(entry.getKey()).unquotedValue(nodeString)
.endObject();
}
jsonStreamWriter.endArray()
.endObject();
writer.flush();
return writer.toString();
} catch (final IOException e) {
throw new ODataRuntimeException("IOException: ", e);
} catch (final EdmException e) {
throw new ODataRuntimeException("EdmException: ", e);
}
}
public class ExpandSelectTreeNodeBuilderImpl extends ExpandSelectTreeNodeBuilder {
private EdmEntitySet entitySet;
private List<String> selectedPropertyNames;
private List<String> selectedNavigationPropertyNames;
private Map<String, ExpandSelectTreeNode> customExpandedNavigationProperties;
private List<String> expandedNavigationPropertyNames;
@Override
public ExpandSelectTreeNodeBuilder entitySet(final EdmEntitySet entitySet) {
this.entitySet = entitySet;
return this;
}
@Override
public ExpandSelectTreeNode build() throws EdmException {
EdmEntityType entityType = entitySet.getEntityType();
if (selectedPropertyNames != null) {
handleProperties(entityType);
}
if (selectedNavigationPropertyNames != null) {
setAllKindFalse();
handleLinks(entityType, selectedNavigationPropertyNames, null);
}
if (expandedNavigationPropertyNames != null) {
ExpandSelectTreeNodeImpl subNode = new ExpandSelectTreeNodeImpl();
subNode.setExplicitlySelected();
handleLinks(entityType, expandedNavigationPropertyNames, subNode);
}
if (customExpandedNavigationProperties != null) {
handleCustomLinks(entityType);
}
return ExpandSelectTreeNodeImpl.this;
}
private void handleCustomLinks(final EdmEntityType entityType) throws EdmException {
for (Map.Entry<String, ExpandSelectTreeNode> entry : customExpandedNavigationProperties.entrySet()) {
EdmTyped navigationProperty = entityType.getProperty(entry.getKey());
if (navigationProperty == null) {
throw new EdmException(EdmException.NAVIGATIONPROPERTYNOTFOUND.addContent(entry.getKey()));
}
if (!(navigationProperty instanceof EdmNavigationProperty)) {
throw new EdmException(EdmException.MUSTBENAVIGATIONPROPERTY.addContent(entry.getKey()));
}
putLink(entry.getKey(), (ExpandSelectTreeNodeImpl) entry.getValue());
}
}
private void handleLinks(final EdmEntityType entityType, final List<String> names,
final ExpandSelectTreeNodeImpl subNode) throws EdmException {
for (String navigationPropertyName : names) {
EdmTyped navigationProperty = entityType.getProperty(navigationPropertyName);
if (navigationProperty == null) {
throw new EdmException(EdmException.NAVIGATIONPROPERTYNOTFOUND.addContent(navigationPropertyName));
} else if (!(navigationProperty instanceof EdmNavigationProperty)) {
throw new EdmException(EdmException.MUSTBENAVIGATIONPROPERTY.addContent(navigationPropertyName));
}
putLink(navigationPropertyName, subNode);
}
}
private void handleProperties(final EdmEntityType entityType) throws EdmException {
for (String propertyName : selectedPropertyNames) {
EdmTyped property = entityType.getProperty(propertyName);
if (property == null) {
throw new EdmException(EdmException.PROPERTYNOTFOUND.addContent(propertyName));
} else if (!(property instanceof EdmProperty)) {
throw new EdmException(EdmException.MUSTBEPROPERTY.addContent(propertyName));
}
addProperty((EdmProperty) property);
}
}
@Override
public ExpandSelectTreeNodeBuilder selectedProperties(final List<String> selectedPropertyNames) {
this.selectedPropertyNames = selectedPropertyNames;
return this;
}
@Override
public ExpandSelectTreeNodeBuilder selectedLinks(final List<String> selectedNavigationPropertyNames) {
this.selectedNavigationPropertyNames = selectedNavigationPropertyNames;
return this;
}
@Override
public ExpandSelectTreeNodeBuilder
customExpandedLink(final String navigationPropertyName, final ExpandSelectTreeNode expandNode) {
if (expandNode == null) {
throw new ODataRuntimeException("ExpandNode must not be null");
}
if (customExpandedNavigationProperties == null) {
customExpandedNavigationProperties = new HashMap<String, ExpandSelectTreeNode>();
}
customExpandedNavigationProperties.put(navigationPropertyName, expandNode);
return this;
}
@Override
public ExpandSelectTreeNodeBuilder expandedLinks(final List<String> navigationPropertyNames) {
expandedNavigationPropertyNames = navigationPropertyNames;
return this;
}
}
}