You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by il...@apache.org on 2014/04/27 07:49:17 UTC
[4/6] [OLINGO-254] Specific client (EdmEnabledODataClient) provided
to work with Edm: type information is derived from contextURL,
hence such client is useful in JSON with full or minimal metadata
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15e7718a/fit/src/main/java/org/apache/olingo/fit/utils/XMLUtilities.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/XMLUtilities.java b/fit/src/main/java/org/apache/olingo/fit/utils/XMLUtilities.java
new file mode 100644
index 0000000..162221a
--- /dev/null
+++ b/fit/src/main/java/org/apache/olingo/fit/utils/XMLUtilities.java
@@ -0,0 +1,1132 @@
+/*
+ * 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.fit.utils;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.nio.charset.Charset;
+import java.util.AbstractMap;
+import java.util.AbstractMap.SimpleEntry;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.ws.rs.NotFoundException;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLEventFactory;
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.XMLEventWriter;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.events.Attribute;
+import javax.xml.stream.events.StartElement;
+import javax.xml.stream.events.XMLEvent;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.vfs2.FileObject;
+import org.apache.commons.vfs2.FileSystemException;
+import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
+import org.apache.olingo.fit.metadata.Metadata;
+import org.apache.olingo.fit.metadata.NavigationProperty;
+
+public class XMLUtilities extends AbstractUtilities {
+
+ protected static XMLInputFactory ifactory = null;
+
+ protected static XMLOutputFactory ofactory = null;
+
+ public XMLUtilities(final ODataServiceVersion version) throws Exception {
+ super(version);
+ }
+
+ @Override
+ protected Accept getDefaultFormat() {
+ return Accept.ATOM;
+ }
+
+ protected XMLEventReader getEventReader(final InputStream is) throws XMLStreamException {
+ if (ifactory == null) {
+ ifactory = XMLInputFactory.newInstance();
+ }
+ ifactory.setProperty(XMLInputFactory.IS_NAMESPACE_AWARE, false);
+ return ifactory.createXMLEventReader(is, "UTF-8");
+ }
+
+ protected static XMLEventWriter getEventWriter(final OutputStream os) throws XMLStreamException {
+ if (ofactory == null) {
+ ofactory = XMLOutputFactory.newInstance();
+ }
+
+ return ofactory.createXMLEventWriter(os, "UTF-8");
+ }
+
+ private void writeEvent(final XMLEvent event, final XMLEventWriter writer) {
+ if (writer != null) {
+ try {
+ writer.add(event);
+ } catch (XMLStreamException e) {
+ LOG.error("Error writing event {}", event, e);
+ }
+ }
+ }
+
+ private void skipElement(
+ final StartElement start,
+ final XMLEventReader reader,
+ final XMLEventWriter writer,
+ final boolean excludeStart)
+ throws Exception {
+
+ if (!excludeStart) {
+ writeEvent(start, writer);
+ }
+
+ int depth = 1;
+ boolean found = false;
+
+ while (reader.hasNext() && !found) {
+ final XMLEvent event = reader.nextEvent();
+
+ writeEvent(event, writer);
+
+ if (event.getEventType() == XMLStreamConstants.START_ELEMENT) {
+ depth++;
+ } else if (event.getEventType() == XMLStreamConstants.END_ELEMENT) {
+ depth--;
+ found = depth == 0 && start.getName().equals(event.asEndElement().getName());
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc }
+ */
+ @Override
+ protected InputStream addLinks(
+ final String entitySetName, final String entitykey, final InputStream is, final Set<String> links)
+ throws Exception {
+
+ // -----------------------------------------
+ // 0. Build reader and writer
+ // -----------------------------------------
+ final XMLEventReader reader = getEventReader(is);
+ final XMLEventFactory eventFactory = XMLEventFactory.newInstance();
+
+ final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ final XMLEventWriter writer = getEventWriter(bos);
+ // -----------------------------------------
+ final Map.Entry<Integer, XMLElement> entry =
+ extractElement(reader, writer, Collections.singletonList("entry"), 0, 1, 1);
+
+ writer.add(entry.getValue().getStart());
+
+ final Metadata metadata = Commons.getMetadata(version);
+ final Map<String, NavigationProperty> navigationProperties = metadata.getNavigationProperties(entitySetName);
+
+ // add for links
+ for (String link : links) {
+ final Set<Attribute> attributes = new HashSet<Attribute>();
+ attributes.add(eventFactory.createAttribute(new QName("title"), link));
+ attributes.add(eventFactory.createAttribute(new QName("href"),
+ Commons.getLinksURI(version, entitySetName, entitykey, link)));
+ attributes.add(eventFactory.createAttribute(new QName("rel"),
+ Constants.get(version, ConstantKey.ATOM_LINK_REL) + link));
+ attributes.add(eventFactory.createAttribute(new QName("type"),
+ navigationProperties.get(link).isFeed()
+ ? Constants.get(version, ConstantKey.ATOM_LINK_FEED)
+ : Constants.get(version, ConstantKey.ATOM_LINK_ENTRY)));
+
+ writer.add(eventFactory.createStartElement(
+ new QName(Constants.get(version, ConstantKey.LINK)), attributes.iterator(), null));
+ writer.add(eventFactory.createEndElement(new QName(Constants.get(version, ConstantKey.LINK)), null));
+ }
+
+ writer.add(entry.getValue().getContentReader());
+ writer.add(entry.getValue().getEnd());
+ writer.add(reader);
+ IOUtils.closeQuietly(is);
+
+ writer.flush();
+ writer.close();
+ reader.close();
+
+ return new ByteArrayInputStream(bos.toByteArray());
+ }
+
+ /**
+ * {@inheritDoc }
+ */
+ @Override
+ protected Set<String> retrieveAllLinkNames(final InputStream is) throws Exception {
+ final Set<String> links = new HashSet<String>();
+
+ final XMLEventReader reader = getEventReader(is);
+
+ try {
+
+ int startDepth = 0;
+
+ while (true) {
+ final Map.Entry<Integer, XMLElement> linkInfo =
+ extractElement(reader, null,
+ Collections.<String>singletonList(Constants.get(version, ConstantKey.LINK)), startDepth, 2, 2);
+
+ startDepth = linkInfo.getKey();
+
+ links.add(linkInfo.getValue().getStart().getAttributeByName(new QName("title")).getValue());
+ }
+ } catch (Exception ignore) {
+ // ignore
+ } finally {
+ reader.close();
+ IOUtils.closeQuietly(is);
+ }
+
+ return links;
+ }
+
+ /**
+ * {@inheritDoc }
+ */
+ @Override
+ protected NavigationLinks retrieveNavigationInfo(
+ final String entitySetName, final InputStream is)
+ throws Exception {
+
+ final NavigationLinks links = new NavigationLinks();
+
+ final XMLEventReader reader = getEventReader(is);
+
+ try {
+ final List<Map.Entry<String, String>> filter = new ArrayList<Map.Entry<String, String>>();
+ filter.add(new AbstractMap.SimpleEntry<String, String>("type", "application/atom+xml;type=entry"));
+ filter.add(new AbstractMap.SimpleEntry<String, String>("type", "application/atom+xml;type=feed"));
+
+ int startDepth = 0;
+
+ while (true) {
+ // a. search for link with type attribute equals to "application/atom+xml;type=entry/feed"
+ final Map.Entry<Integer, XMLElement> linkInfo = extractElement(
+ reader, null, Collections.<String>singletonList(Constants.get(version, ConstantKey.LINK)),
+ filter, true, startDepth, 2, 2);
+ final XMLElement link = linkInfo.getValue();
+ startDepth = linkInfo.getKey();
+
+ final String title = link.getStart().getAttributeByName(new QName("title")).getValue();
+
+ final Attribute hrefAttr = link.getStart().getAttributeByName(new QName("href"));
+ final String href = hrefAttr == null ? null : hrefAttr.getValue();
+
+ try {
+ final XMLElement inlineElement =
+ extractElement(link.getContentReader(), null,
+ Collections.<String>singletonList(Constants.get(version, ConstantKey.INLINE)), 0, -1, -1).
+ getValue();
+ final XMLEventReader inlineReader = inlineElement.getContentReader();
+
+ try {
+ while (true) {
+ final XMLElement entry =
+ extractElement(inlineReader, null, Collections.<String>singletonList("entry"), 0, -1, -1).
+ getValue();
+ links.addInlines(title, entry.toStream());
+ }
+ } catch (Exception e) {
+ // Reached the end of document
+ }
+
+ inlineReader.close();
+ } catch (Exception ignore) {
+ // inline element not found (inlines are not mondatory).
+ if (StringUtils.isNotBlank(href) && ENTITY_URI_PATTERN.matcher(href).matches()) {
+ links.addLinks(title, href.substring(href.lastIndexOf('/') + 1));
+ }
+ }
+ }
+ } catch (Exception ignore) {
+ // ignore
+ } finally {
+ reader.close();
+ }
+
+ return links;
+ }
+
+ /**
+ * {@inheritDoc }
+ */
+ @Override
+ protected InputStream normalizeLinks(
+ final String entitySetName, final String entityKey, final InputStream is, final NavigationLinks links)
+ throws Exception {
+
+ // -----------------------------------------
+ // 0. Build reader and writer
+ // -----------------------------------------
+ final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ IOUtils.copy(is, bos);
+ is.close();
+
+ final ByteArrayOutputStream tmpBos = new ByteArrayOutputStream();
+ final XMLEventWriter writer = getEventWriter(tmpBos);
+
+ final XMLEventReader reader = getEventReader(new ByteArrayInputStream(bos.toByteArray()));
+ // -----------------------------------------
+
+ // -----------------------------------------
+ // 1. Normalize links
+ // -----------------------------------------
+ final Set<String> added = new HashSet<String>();
+
+ try {
+ final List<Map.Entry<String, String>> filter = new ArrayList<Map.Entry<String, String>>();
+ filter.add(new AbstractMap.SimpleEntry<String, String>("type", "application/atom+xml;type=entry"));
+ filter.add(new AbstractMap.SimpleEntry<String, String>("type", "application/atom+xml;type=feed"));
+
+ Map.Entry<Integer, XMLElement> linkInfo = null;
+
+ while (true) {
+ // a. search for link with type attribute equals to "application/atom+xml;type=entry/feed"
+ linkInfo = extractElement(
+ reader, writer,
+ Collections.<String>singletonList(Constants.get(version, ConstantKey.LINK)), filter, true,
+ linkInfo == null ? 0 : linkInfo.getKey(), 2, 2);
+ final XMLElement link = linkInfo.getValue();
+
+ final String title = link.getStart().getAttributeByName(new QName("title")).getValue();
+
+ if (!added.contains(title)) {
+ added.add(title);
+
+ final String normalizedLink = String.format(
+ "<link href=\"%s(%s)/%s\" rel=\"%s\" title=\"%s\" type=\"%s\"/>",
+ entitySetName,
+ entityKey,
+ title,
+ link.getStart().getAttributeByName(new QName("rel")).getValue(),
+ title,
+ link.getStart().getAttributeByName(new QName("type")).getValue());
+
+ addAtomElement(IOUtils.toInputStream(normalizedLink, Constants.ENCODING), writer);
+ }
+ }
+ } catch (Exception ignore) {
+ // ignore
+ } finally {
+ writer.close();
+ reader.close();
+ }
+ // -----------------------------------------
+
+ // -----------------------------------------
+ // 2. Add edit link if missing
+ // -----------------------------------------
+ final InputStream content = addEditLink(
+ new ByteArrayInputStream(tmpBos.toByteArray()),
+ entitySetName,
+ Constants.get(version, ConstantKey.DEFAULT_SERVICE_URL) + entitySetName + "(" + entityKey + ")");
+ // -----------------------------------------
+
+ // -----------------------------------------
+ // 3. Add content element if missing
+ // -----------------------------------------
+ return addAtomContent(
+ content,
+ entitySetName,
+ Constants.get(version, ConstantKey.DEFAULT_SERVICE_URL) + entitySetName + "(" + entityKey + ")");
+ // -----------------------------------------
+
+ }
+
+ public XMLElement getXmlElement(
+ final StartElement start,
+ final XMLEventReader reader)
+ throws Exception {
+
+ final XMLElement res = new XMLElement();
+ res.setStart(start);
+
+ final Charset encoding = Charset.forName("UTF-8");
+ final ByteArrayOutputStream content = new ByteArrayOutputStream();
+ final OutputStreamWriter writer = new OutputStreamWriter(content, encoding);
+
+ int depth = 1;
+
+ while (reader.hasNext() && depth > 0) {
+ final XMLEvent event = reader.nextEvent();
+
+ if (event.getEventType() == XMLStreamConstants.START_ELEMENT) {
+ depth++;
+ } else if (event.getEventType() == XMLStreamConstants.END_ELEMENT) {
+ depth--;
+ }
+
+ if (depth == 0) {
+ res.setEnd(event.asEndElement());
+ } else {
+ event.writeAsEncodedUnicode(writer);
+ }
+ }
+
+ writer.flush();
+ writer.close();
+
+ res.setContent(new ByteArrayInputStream(content.toByteArray()));
+
+ return res;
+ }
+
+ private void addAtomElement(
+ final InputStream content,
+ final XMLEventWriter writer)
+ throws Exception {
+ final XMLEventReader reader = getEventReader(content);
+
+ final XMLEventFactory eventFactory = XMLEventFactory.newInstance();
+ XMLEvent newLine = eventFactory.createSpace("\n");
+
+ try {
+ writer.add(newLine);
+
+ while (reader.hasNext()) {
+ final XMLEvent event = reader.nextEvent();
+
+ if (event.getEventType() != XMLStreamConstants.START_DOCUMENT
+ && event.getEventType() != XMLStreamConstants.END_DOCUMENT
+ && event.getEventType() != XMLStreamConstants.COMMENT) {
+ writer.add(event);
+ }
+ }
+ writer.add(newLine);
+ } finally {
+ reader.close();
+ IOUtils.closeQuietly(content);
+ }
+ }
+
+ @Override
+ public InputStream addEditLink(
+ final InputStream content, final String title, final String href)
+ throws Exception {
+
+ final ByteArrayOutputStream copy = new ByteArrayOutputStream();
+ IOUtils.copy(content, copy);
+ IOUtils.closeQuietly(content);
+
+ XMLEventReader reader = getEventReader(new ByteArrayInputStream(copy.toByteArray()));
+
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ XMLEventWriter writer = getEventWriter(bos);
+
+ final String editLinkElement = String.format("<link rel=\"edit\" title=\"%s\" href=\"%s\" />", title, href);
+
+ try {
+ // check edit link existence
+ extractElement(reader, writer, Collections.<String>singletonList(Constants.get(version, ConstantKey.LINK)),
+ Collections.<Map.Entry<String, String>>singletonList(
+ new AbstractMap.SimpleEntry<String, String>("rel", "edit")), false, 0, -1, -1);
+
+ addAtomElement(IOUtils.toInputStream(editLinkElement, Constants.ENCODING), writer);
+ writer.add(reader);
+
+ } catch (Exception e) {
+ reader.close();
+ reader = getEventReader(new ByteArrayInputStream(copy.toByteArray()));
+
+ bos = new ByteArrayOutputStream();
+ writer = getEventWriter(bos);
+
+ final XMLElement entryElement =
+ extractElement(reader, writer, Collections.<String>singletonList("entry"), 0, 1, 1).getValue();
+
+ writer.add(entryElement.getStart());
+
+ addAtomElement(IOUtils.toInputStream(editLinkElement, Constants.ENCODING), writer);
+
+ writer.add(entryElement.getContentReader());
+ writer.add(entryElement.getEnd());
+
+ writer.add(reader);
+
+ writer.flush();
+ writer.close();
+ } finally {
+ reader.close();
+ }
+
+ return new ByteArrayInputStream(bos.toByteArray());
+ }
+
+ @Override
+ public InputStream addOperation(final InputStream content, final String name, final String metaAnchor,
+ final String href) throws Exception {
+
+ final ByteArrayOutputStream copy = new ByteArrayOutputStream();
+ IOUtils.copy(content, copy);
+ IOUtils.closeQuietly(content);
+
+ final String action = String.format("<m:action metadata=\"%s%s\" title=\"%s\" target=\"%s\"/>",
+ Constants.get(version, ConstantKey.DEFAULT_SERVICE_URL), metaAnchor, name, href);
+ final String newContent = new String(copy.toByteArray(), "UTF-8").replaceAll("\\<content ", action + "\\<content ");
+
+ return IOUtils.toInputStream(newContent, "UTF-8");
+ }
+
+ public InputStream addAtomContent(
+ final InputStream content, final String title, final String href)
+ throws Exception {
+
+ final ByteArrayOutputStream copy = new ByteArrayOutputStream();
+ IOUtils.copy(content, copy);
+
+ IOUtils.closeQuietly(content);
+
+ XMLEventReader reader = getEventReader(new ByteArrayInputStream(copy.toByteArray()));
+
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ XMLEventWriter writer = getEventWriter(bos);
+
+ try {
+ // check edit link existence
+ XMLElement contentElement =
+ extractElement(reader, writer, Collections.<String>singletonList("content"), 0, 2, 2).getValue();
+ writer.add(contentElement.getStart());
+ writer.add(contentElement.getContentReader());
+ writer.add(contentElement.getEnd());
+ writer.add(reader);
+ } catch (Exception e) {
+ reader.close();
+ reader = getEventReader(new ByteArrayInputStream(copy.toByteArray()));
+
+ bos = new ByteArrayOutputStream();
+ writer = getEventWriter(bos);
+
+ if (isMediaContent(title)) {
+ final XMLElement entryElement =
+ extractElement(reader, writer, Collections.<String>singletonList("entry"), 0, 1, 1).getValue();
+
+ writer.add(entryElement.getStart());
+ writer.add(entryElement.getContentReader());
+
+ addAtomElement(
+ IOUtils.toInputStream(String.format("<content type=\"*/*\" src=\"%s/$value\" />", href)),
+ writer);
+
+ writer.add(entryElement.getEnd());
+ } else {
+ try {
+ final XMLElement entryElement =
+ extractElement(reader, writer, Collections.<String>singletonList(
+ Constants.get(version, ConstantKey.PROPERTIES)), 0, 2, 3).getValue();
+
+ addAtomElement(
+ IOUtils.toInputStream("<content type=\"application/xml\">"),
+ writer);
+
+ writer.add(entryElement.getStart());
+ writer.add(entryElement.getContentReader());
+ writer.add(entryElement.getEnd());
+
+ addAtomElement(
+ IOUtils.toInputStream("</content>"),
+ writer);
+ } catch (Exception nf) {
+ reader.close();
+ reader = getEventReader(new ByteArrayInputStream(copy.toByteArray()));
+
+ bos = new ByteArrayOutputStream();
+ writer = getEventWriter(bos);
+
+ final XMLElement entryElement =
+ extractElement(reader, writer, Collections.<String>singletonList("entry"), 0, 1, 1).getValue();
+ writer.add(entryElement.getStart());
+ writer.add(entryElement.getContentReader());
+
+ addAtomElement(
+ IOUtils.toInputStream("<content type=\"application/xml\"/>"),
+ writer);
+
+ writer.add(entryElement.getEnd());
+ }
+ }
+
+ writer.add(reader);
+
+ writer.flush();
+ writer.close();
+ } finally {
+ reader.close();
+ }
+
+ return new ByteArrayInputStream(bos.toByteArray());
+ }
+
+ public int countAllElements(final String entitySetName) throws Exception {
+ final String basePath = entitySetName + File.separatorChar;
+ int count = countFeedElements(fsManager.readFile(basePath + Constants.get(version, ConstantKey.FEED), Accept.XML),
+ "entry");
+
+ final String skipTokenDirPath = fsManager.getAbsolutePath(basePath + Constants.get(version, ConstantKey.SKIP_TOKEN),
+ null);
+
+ try {
+ final FileObject skipToken = fsManager.resolve(skipTokenDirPath);
+ final FileObject[] files = fsManager.findByExtension(skipToken, Accept.XML.getExtension().substring(1));
+
+ for (FileObject file : files) {
+ count += countFeedElements(fsManager.readFile(
+ basePath + Constants.get(version, ConstantKey.SKIP_TOKEN) + File.separatorChar
+ + file.getName().getBaseName(), null), "entry");
+ }
+ } catch (FileSystemException fse) {
+ LOG.debug("Resource path '{}' not found", skipTokenDirPath);
+ }
+
+ return count;
+ }
+
+ private int countFeedElements(final InputStream is, final String elementName) throws XMLStreamException {
+ final XMLEventReader reader = getEventReader(is);
+
+ int count = 0;
+
+ while (reader.hasNext()) {
+ final XMLEvent event = reader.nextEvent();
+
+ if (event.getEventType() == XMLStreamConstants.START_ELEMENT
+ && elementName.equals(event.asStartElement().getName().getLocalPart())) {
+ count++;
+ }
+ }
+
+ reader.close();
+ return count;
+ }
+
+ public Map.Entry<Integer, XMLElement> extractElement(
+ final XMLEventReader reader, final XMLEventWriter writer, final List<String> path,
+ final int startPathPos, final int minPathPos, final int maxPathPos)
+ throws Exception {
+ return extractElement(reader, writer, path, null, false, startPathPos, minPathPos, maxPathPos);
+ }
+
+ public Map.Entry<Integer, XMLElement> extractElement(
+ final XMLEventReader reader, final XMLEventWriter writer, final List<String> path,
+ final Collection<Map.Entry<String, String>> filter,
+ final boolean filterInOr,
+ final int startPathPos, final int minPathPos, final int maxPathPos)
+ throws Exception {
+
+ StartElement start = null;
+ int searchFor = 0;
+ int depth = startPathPos;
+
+ // Current inspected element
+ String current = null;
+
+ // set defaults
+ final List<String> pathElementNames = path == null ? Collections.<String>emptyList() : path;
+ final Collection<Map.Entry<String, String>> filterAttrs =
+ filter == null ? Collections.<Map.Entry<String, String>>emptySet() : filter;
+
+ while (reader.hasNext() && start == null) {
+ final XMLEvent event = reader.nextEvent();
+
+ if (event.getEventType() == XMLStreamConstants.START_ELEMENT) {
+ depth++;
+
+ if (current != null || ((minPathPos < 0 || minPathPos <= depth) && (maxPathPos < 0 || depth <= maxPathPos))) {
+ if (pathElementNames.isEmpty()
+ || pathElementNames.get(searchFor).trim().equals(event.asStartElement().getName().getLocalPart())) {
+
+ if (searchFor < pathElementNames.size() - 1) {
+ // path exploring not completed
+ writeEvent(event, writer);
+ current = pathElementNames.get(searchFor).trim();
+ searchFor++;
+ } else {
+
+ // path exploring completed ... evaluate filter about path element name attribute
+ boolean match = filterAttrs.isEmpty() || !filterInOr;
+
+ for (Map.Entry<String, String> filterAttr : filterAttrs) {
+ final Attribute attr = event.asStartElement().getAttributeByName(new QName(filterAttr.getKey().trim()));
+
+ if (attr == null || !filterAttr.getValue().trim().equals(attr.getValue())) {
+ match = filterInOr ? match : false;
+ } else {
+ match = filterInOr ? true : match;
+ }
+ }
+
+ if (match) {
+ // found searched element
+ start = event.asStartElement();
+ } else {
+ skipElement(event.asStartElement(), reader, writer, false);
+ depth--;
+ }
+ }
+ } else if (current == null) {
+ writeEvent(event, writer);
+ } else {
+ // skip element
+ skipElement(event.asStartElement(), reader, writer, false);
+ depth--;
+ }
+ } else {
+ writeEvent(event, writer);
+ }
+
+ } else if (event.getEventType() == XMLStreamConstants.END_ELEMENT) {
+ depth--;
+
+ writeEvent(event, writer);
+
+ if (event.asEndElement().getName().getLocalPart().equals(current)) {
+ // back step ....
+ searchFor--;
+ current = searchFor > 0 ? pathElementNames.get(searchFor - 1).trim() : null;
+ }
+ } else {
+ writeEvent(event, writer);
+ }
+ }
+
+ if (start == null) {
+ throw new NotFoundException();
+ }
+
+ return new SimpleEntry<Integer, XMLElement>(Integer.valueOf(depth - 1), getXmlElement(start, reader));
+ }
+
+ public InputStream addAtomInlinecount(
+ final InputStream feed, final int count, final Accept accept)
+ throws Exception {
+ final XMLEventReader reader = getEventReader(feed);
+
+ final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ final XMLEventWriter writer = getEventWriter(bos);
+
+ try {
+
+ final XMLElement feedElement =
+ extractElement(reader, writer, Collections.<String>singletonList("feed"), 0, 1, 1).getValue();
+
+ writer.add(feedElement.getStart());
+ addAtomElement(IOUtils.toInputStream(String.format("<m:count>%d</m:count>", count), Constants.ENCODING), writer);
+ writer.add(feedElement.getContentReader());
+ writer.add(feedElement.getEnd());
+
+ while (reader.hasNext()) {
+ writer.add(reader.nextEvent());
+ }
+
+ } finally {
+ writer.flush();
+ writer.close();
+ reader.close();
+ IOUtils.closeQuietly(feed);
+ }
+
+ return new ByteArrayInputStream(bos.toByteArray());
+ }
+
+ @Override
+ public InputStream selectEntity(final InputStream entity, final String[] propertyNames) throws Exception {
+ final XMLEventReader reader = getEventReader(entity);
+
+ final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ final XMLEventWriter writer = getEventWriter(bos);
+
+ final List<String> found = new ArrayList<String>(Arrays.asList(propertyNames));
+
+ boolean inProperties = false;
+ boolean writeCurrent = true;
+ Boolean writeNext = null;
+ String currentName = null;
+
+ final List<String> fieldToBeSaved = new ArrayList<String>(Arrays.asList(propertyNames));
+
+ while (reader.hasNext()) {
+ final XMLEvent event = reader.nextEvent();
+ if (event.getEventType() == XMLStreamConstants.START_ELEMENT
+ && Constants.get(version, ConstantKey.LINK).equals(event.asStartElement().getName().getLocalPart())
+ && !fieldToBeSaved.contains(
+ event.asStartElement().getAttributeByName(new QName("title")).getValue())
+ && !"edit".equals(event.asStartElement().getAttributeByName(new QName("rel")).getValue())) {
+ writeCurrent = false;
+ } else if (event.getEventType() == XMLStreamConstants.END_ELEMENT
+ && Constants.get(version, ConstantKey.LINK).equals(event.asEndElement().getName().getLocalPart())) {
+ writeNext = true;
+ } else if (event.getEventType() == XMLStreamConstants.START_ELEMENT
+ && (Constants.get(version, ConstantKey.PROPERTIES)).equals(
+ event.asStartElement().getName().getLocalPart())) {
+ writeCurrent = true;
+ writeNext = false;
+ inProperties = true;
+ } else if (event.getEventType() == XMLStreamConstants.END_ELEMENT
+ && (Constants.get(version, ConstantKey.PROPERTIES)).equals(
+ event.asEndElement().getName().getLocalPart())) {
+ writeCurrent = true;
+ } else if (inProperties) {
+ if (event.getEventType() == XMLStreamConstants.START_ELEMENT) {
+ final String elementName = event.asStartElement().getName().getLocalPart();
+
+ for (String propertyName : propertyNames) {
+ if ((Constants.get(version, ConstantKey.ATOM_PROPERTY_PREFIX) + propertyName.trim()).equals(elementName)) {
+ writeCurrent = true;
+ found.remove(propertyName);
+ currentName = propertyName;
+ }
+ }
+
+ } else if (event.getEventType() == XMLStreamConstants.END_ELEMENT
+ && StringUtils.isNotBlank(currentName)
+ && (Constants.get(version, ConstantKey.ATOM_PROPERTY_PREFIX) + currentName.trim()).equals(
+ event.asEndElement().getName().getLocalPart())) {
+ writeNext = false;
+ currentName = null;
+ }
+
+ }
+
+ if (writeCurrent) {
+ writer.add(event);
+ }
+
+ if (writeNext != null) {
+ writeCurrent = writeNext;
+ writeNext = null;
+ }
+ }
+
+ writer.flush();
+ writer.close();
+ reader.close();
+ IOUtils.closeQuietly(entity);
+
+ // Do not raise any exception in order to support FC properties as well
+ // if (!found.isEmpty()) {
+ // throw new Exception(String.format("Could not find a properties '%s'", found));
+ // }
+ return new ByteArrayInputStream(bos.toByteArray());
+ }
+
+ @Override
+ public InputStream readEntities(
+ final List<String> links, final String linkName, final String next, final boolean forceFeed)
+ throws Exception {
+
+ if (links.isEmpty()) {
+ throw new NotFoundException();
+ }
+
+ final Charset encoding = Charset.forName("UTF-8");
+
+ final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ final OutputStreamWriter writer = new OutputStreamWriter(bos, encoding);
+
+ writer.write("<?xml version=\"1.0\" encoding=\"utf-8\"?>".toCharArray());
+
+ if (forceFeed || links.size() > 1) {
+ // build a feed
+
+ writer.write(("<feed xml:base=\"" + Constants.get(version, ConstantKey.DEFAULT_SERVICE_URL) + "\" "
+ + "xmlns=\"http://www.w3.org/2005/Atom\" "
+ + "xmlns:d=\"http://schemas.microsoft.com/ado/2007/08/dataservices\" "
+ + "xmlns:m=\"http://schemas.microsoft.com/ado/2007/08/dataservices/metadata\">")
+ .toCharArray());
+
+ writer.write(("<id>" + Constants.get(version, ConstantKey.DEFAULT_SERVICE_URL) + "entityset(entityid)/" + linkName
+ + "</id>").toCharArray());
+
+ writer.write(("<title type=\"text\">" + linkName + "</title>").toCharArray());
+ writer.write("<updated>2014-03-03T13:40:49Z</updated>".toCharArray());
+ writer.write(("<link rel=\"self\" title=\"" + linkName + "\" href=\"" + linkName + "\" />").toCharArray());
+ }
+
+ for (String link : links) {
+ try {
+ final Map.Entry<String, String> uri = Commons.parseEntityURI(link);
+
+ final XMLElement entry =
+ extractElement(
+ getEventReader(readEntity(uri.getKey(), uri.getValue(), Accept.ATOM).getValue()),
+ null,
+ Collections.<String>singletonList("entry"),
+ 0, 1, 1).getValue();
+
+ IOUtils.copy(entry.toStream(), writer, encoding);
+ } catch (Exception e) {
+ // log and ignore link
+ LOG.warn("Error parsing uri {}", link, e);
+ }
+ }
+
+ if (forceFeed || links.size() > 1) {
+
+ if (StringUtils.isNotBlank(next)) {
+ writer.write(String.format("<link rel=\"next\" href=\"%s\" />", next).toCharArray());
+ }
+
+ writer.write("</feed>".toCharArray());
+ }
+
+ writer.flush();
+ writer.close();
+
+ return new ByteArrayInputStream(bos.toByteArray());
+ }
+
+ @Override
+ public Map<String, InputStream> getChanges(final InputStream src) throws Exception {
+ final Map<String, InputStream> res = new HashMap<String, InputStream>();
+
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ IOUtils.copy(src, bos);
+ IOUtils.closeQuietly(src);
+
+ // retrieve properties ...
+ XMLEventReader reader = getEventReader(new ByteArrayInputStream(bos.toByteArray()));
+
+ final Map.Entry<Integer, XMLElement> propertyElement =
+ extractElement(reader, null,
+ Collections.<String>singletonList(Constants.get(version, ConstantKey.PROPERTIES)), 0, 2, 3);
+ reader.close();
+
+ reader = propertyElement.getValue().getContentReader();
+
+ try {
+ while (true) {
+ final XMLElement property = extractElement(reader, null, null, 0, -1, -1).getValue();
+ res.put(property.getStart().getName().getLocalPart(), property.toStream());
+ }
+ } catch (Exception ignore) {
+ // end
+ }
+
+ reader.close();
+
+ // retrieve links ...
+ reader = getEventReader(new ByteArrayInputStream(bos.toByteArray()));
+
+ try {
+ int pos = 0;
+ while (true) {
+ final Map.Entry<Integer, XMLElement> linkElement =
+ extractElement(reader, null,
+ Collections.<String>singletonList(Constants.get(version, ConstantKey.LINK)), pos, 2, 2);
+
+ res.put("[Constants.get(version, ConstantKey.LINK)]"
+ + linkElement.getValue().getStart().getAttributeByName(new QName("title")).getValue(),
+ linkElement.getValue().toStream());
+
+ pos = linkElement.getKey();
+ }
+ } catch (Exception ignore) {
+ // end
+ }
+
+ return res;
+ }
+
+ @Override
+ protected InputStream replaceLink(
+ final InputStream toBeChanged, final String linkName, final InputStream replacement)
+ throws Exception {
+ final XMLEventReader reader = getEventReader(toBeChanged);
+
+ final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ final XMLEventWriter writer = getEventWriter(bos);
+
+ final XMLEventFactory eventFactory = XMLEventFactory.newInstance();
+ XMLEvent newLine = eventFactory.createSpace("\n");
+
+ try {
+ final XMLElement linkElement =
+ extractElement(reader, writer,
+ Collections.<String>singletonList(Constants.get(version, ConstantKey.LINK)),
+ Collections.<Map.Entry<String, String>>singletonList(
+ new SimpleEntry<String, String>("title", linkName)), false, 0, -1, -1).getValue();
+ writer.add(linkElement.getStart());
+
+ // ------------------------------------------
+ // write inline ...
+ // ------------------------------------------
+ writer.add(newLine);
+ writer.add(eventFactory.createStartElement("m", null, "inline"));
+
+ addAtomElement(replacement, writer);
+
+ writer.add(eventFactory.createEndElement("m", null, "inline"));
+ writer.add(newLine);
+ // ------------------------------------------
+
+ writer.add(linkElement.getEnd());
+
+ writer.add(reader);
+ writer.flush();
+ writer.close();
+ } finally {
+ reader.close();
+ IOUtils.closeQuietly(toBeChanged);
+ }
+
+ return new ByteArrayInputStream(bos.toByteArray());
+ }
+
+ @Override
+ public Map.Entry<String, List<String>> extractLinkURIs(
+ final String entitySetName, final String entityId, final String linkName)
+ throws Exception {
+
+ final LinkInfo links = readLinks(entitySetName, entityId, linkName, Accept.XML);
+ return extractLinkURIs(links.getLinks());
+ }
+
+ @Override
+ public Map.Entry<String, List<String>> extractLinkURIs(final InputStream is)
+ throws Exception {
+ final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ IOUtils.copy(is, bos);
+ IOUtils.closeQuietly(is);
+
+ XMLEventReader reader = getEventReader(new ByteArrayInputStream(bos.toByteArray()));
+ final List<String> links = new ArrayList<String>();
+ try {
+ while (true) {
+ links.add(IOUtils.toString(extractElement(reader, null, Collections.<String>singletonList("uri"), 0, -1, -1).
+ getValue().getContent()));
+ }
+ } catch (Exception ignore) {
+ // End document reached ...
+ }
+ reader.close();
+
+ String next;
+
+ reader = getEventReader(new ByteArrayInputStream(bos.toByteArray()));
+ try {
+ next = IOUtils.toString(extractElement(reader, null, Collections.<String>singletonList("next"), 0, -1, -1).
+ getValue().getContent());
+ } catch (Exception ignore) {
+ // next link is not mandatory
+ next = null;
+ }
+ reader.close();
+
+ return new AbstractMap.SimpleEntry<String, List<String>>(next, links);
+ }
+
+ @Override
+ public InputStream replaceProperty(
+ final InputStream src, final InputStream replacement, final List<String> path, final boolean justValue)
+ throws Exception {
+
+ final List<String> pathElements = new ArrayList<String>();
+
+ for (String element : path) {
+ pathElements.add(Constants.get(version, ConstantKey.ATOM_PROPERTY_PREFIX) + element);
+ }
+
+ final XMLEventReader reader = getEventReader(src);
+
+ final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ final XMLEventWriter writer = getEventWriter(bos);
+
+ final Map.Entry<Integer, XMLElement> element = extractElement(reader, writer, pathElements, 0, 3, 4);
+
+ if (justValue) {
+ writer.add(element.getValue().getStart());
+ }
+
+ final XMLEventReader changesReader = new XMLEventReaderWrapper(replacement);
+
+ while (changesReader.hasNext()) {
+ final XMLEvent event = changesReader.nextEvent();
+ if (event.isStartElement() && event.asStartElement().getName().equals(element.getValue().getStart().getName())) {
+ writer.add(element.getValue().getStart());
+ writer.add(changesReader);
+ } else {
+ writer.add(event);
+ }
+ }
+
+ changesReader.close();
+ IOUtils.closeQuietly(replacement);
+
+ if (justValue) {
+ writer.add(element.getValue().getEnd());
+ }
+
+ writer.add(reader);
+
+ reader.close();
+ IOUtils.closeQuietly(src);
+
+ writer.flush();
+ writer.close();
+
+ return new ByteArrayInputStream(bos.toByteArray());
+ }
+
+ @Override
+ public InputStream deleteProperty(final InputStream src, final List<String> path) throws Exception {
+ final List<String> pathElements = new ArrayList<String>();
+
+ for (String element : path) {
+ pathElements.add(Constants.get(version, ConstantKey.ATOM_PROPERTY_PREFIX) + element);
+ }
+
+ final XMLEventReader reader = getEventReader(src);
+
+ final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ final XMLEventWriter writer = getEventWriter(bos);
+
+ final Map.Entry<Integer, XMLElement> element = extractElement(reader, writer, pathElements, 0, 3, 4);
+
+ final XMLEventReader changesReader = new XMLEventReaderWrapper(IOUtils.toInputStream(
+ String.format("<%s m:null=\"true\" />", path.get(path.size() - 1)), Constants.ENCODING));
+
+ writer.add(changesReader);
+ changesReader.close();
+
+ writer.add(reader);
+
+ reader.close();
+ IOUtils.closeQuietly(src);
+
+ writer.flush();
+ writer.close();
+
+ return new ByteArrayInputStream(bos.toByteArray());
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15e7718a/fit/src/main/java/org/apache/olingo/fit/utils/XmlElement.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/XmlElement.java b/fit/src/main/java/org/apache/olingo/fit/utils/XmlElement.java
deleted file mode 100644
index 850c862..0000000
--- a/fit/src/main/java/org/apache/olingo/fit/utils/XmlElement.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * 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.fit.utils;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStreamWriter;
-import java.nio.charset.Charset;
-import javax.xml.stream.XMLEventReader;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.stream.events.EndElement;
-import javax.xml.stream.events.StartElement;
-import org.apache.commons.io.IOUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class XmlElement {
-
- /**
- * Logger.
- */
- protected static final Logger LOG = LoggerFactory.getLogger(XmlElement.class);
-
- private static Charset encoding = Charset.forName("UTF-8");
-
- private StartElement start;
-
- private EndElement end;
-
- private ByteArrayOutputStream content = new ByteArrayOutputStream();
-
- public StartElement getStart() {
- return start;
- }
-
- public void setStart(StartElement start) {
- this.start = start;
- }
-
- public EndElement getEnd() {
- return end;
- }
-
- public void setEnd(EndElement end) {
- this.end = end;
- }
-
- public InputStream getContent() throws XMLStreamException {
- return new ByteArrayInputStream(content.toByteArray());
- }
-
- public XMLEventReader getContentReader() throws Exception {
- return new XMLEventReaderWrapper(getContent());
- }
-
- public void setContent(final InputStream content) throws IOException {
- this.content.reset();
-
- final InputStreamReader reader = new InputStreamReader(content, encoding);
- final OutputStreamWriter writer = new OutputStreamWriter(this.content, encoding);
- IOUtils.copyLarge(reader, writer);
-
- writer.flush();
- IOUtils.closeQuietly(reader);
- IOUtils.closeQuietly(writer);
- IOUtils.closeQuietly(content);
- }
-
- public InputStream toStream() throws Exception {
- InputStream res;
- try {
- final ByteArrayOutputStream bos = new ByteArrayOutputStream();
- final OutputStreamWriter osw = new OutputStreamWriter(bos, encoding);
-
- getStart().writeAsEncodedUnicode(osw);
-
- IOUtils.copy(getContent(), osw, encoding);
-
- getEnd().writeAsEncodedUnicode(osw);
- osw.flush();
- osw.close();
-
- res = new ByteArrayInputStream(bos.toByteArray());
- } catch (Exception e) {
- LOG.error("Error serializing elemnt", e);
- res = null;
- }
- return res;
- }
-}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15e7718a/fit/src/main/java/org/apache/olingo/fit/utils/v3/JSONUtilities.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/v3/JSONUtilities.java b/fit/src/main/java/org/apache/olingo/fit/utils/v3/JSONUtilities.java
deleted file mode 100644
index 24b6c55..0000000
--- a/fit/src/main/java/org/apache/olingo/fit/utils/v3/JSONUtilities.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * 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.fit.utils.v3;
-
-import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
-
-public class JSONUtilities extends org.apache.olingo.fit.utils.AbstractJSONUtilities {
-
- public JSONUtilities() throws Exception {
- super(ODataServiceVersion.V30);
- }
-}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15e7718a/fit/src/main/java/org/apache/olingo/fit/utils/v3/XMLUtilities.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/v3/XMLUtilities.java b/fit/src/main/java/org/apache/olingo/fit/utils/v3/XMLUtilities.java
deleted file mode 100644
index 2eb0983..0000000
--- a/fit/src/main/java/org/apache/olingo/fit/utils/v3/XMLUtilities.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * 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.fit.utils.v3;
-
-import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
-
-public class XMLUtilities extends org.apache.olingo.fit.utils.AbstractXMLUtilities {
-
- public XMLUtilities() throws Exception {
- super(ODataServiceVersion.V30);
- }
-}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15e7718a/fit/src/main/java/org/apache/olingo/fit/utils/v4/JSONUtilities.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/v4/JSONUtilities.java b/fit/src/main/java/org/apache/olingo/fit/utils/v4/JSONUtilities.java
deleted file mode 100644
index 9b2d607..0000000
--- a/fit/src/main/java/org/apache/olingo/fit/utils/v4/JSONUtilities.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * 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.fit.utils.v4;
-
-import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
-
-public class JSONUtilities extends org.apache.olingo.fit.utils.AbstractJSONUtilities {
-
- public JSONUtilities() throws Exception {
- super(ODataServiceVersion.V40);
- }
-}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15e7718a/fit/src/main/java/org/apache/olingo/fit/utils/v4/XMLUtilities.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/v4/XMLUtilities.java b/fit/src/main/java/org/apache/olingo/fit/utils/v4/XMLUtilities.java
deleted file mode 100644
index 86e6e3c..0000000
--- a/fit/src/main/java/org/apache/olingo/fit/utils/v4/XMLUtilities.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * 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.fit.utils.v4;
-
-import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
-
-public class XMLUtilities extends org.apache.olingo.fit.utils.AbstractXMLUtilities {
-
- public XMLUtilities() throws Exception {
- super(ODataServiceVersion.V40);
- }
-}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15e7718a/lib/client-api/src/main/java/org/apache/olingo/client/api/CommonEdmEnabledODataClient.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/CommonEdmEnabledODataClient.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/CommonEdmEnabledODataClient.java
new file mode 100644
index 0000000..2b5478f
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/CommonEdmEnabledODataClient.java
@@ -0,0 +1,44 @@
+/*
+ * 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.client.api;
+
+import java.net.URI;
+import org.apache.olingo.client.api.communication.request.cud.CommonUpdateType;
+import org.apache.olingo.commons.api.edm.Edm;
+
+/**
+ * Client interface that caches the Edm metadata information for a given service root.
+ * <br/>
+ * Be aware that any request generated via this client instance will be performed against the given service root.
+ *
+ * @param <UT> concrete update type, depending on the protocol version
+ */
+public interface CommonEdmEnabledODataClient<UT extends CommonUpdateType> extends CommonODataClient<UT> {
+
+ String getServiceRoot();
+
+ /**
+ * Checks if the cached Edm matadata information matches the argument and, if not, updates the cache against the
+ * configured service root.
+ *
+ * @param metadataETag metadata ETag to be compared against the cache
+ * @return Edm
+ */
+ Edm getEdm(String metadataETag);
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15e7718a/lib/client-api/src/main/java/org/apache/olingo/client/api/CommonODataClient.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/CommonODataClient.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/CommonODataClient.java
index b3a4427..fccaa54 100644
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/CommonODataClient.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/CommonODataClient.java
@@ -36,6 +36,11 @@ import org.apache.olingo.client.api.uri.CommonURIBuilder;
import org.apache.olingo.client.api.uri.CommonFilterFactory;
import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
+/**
+ * Generic client interface (common to all supported OData protocol versions).
+ *
+ * @param <UT> concrete update type, depending on the protocol version
+ */
public interface CommonODataClient<UT extends CommonUpdateType> {
ODataServiceVersion getServiceVersion();
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15e7718a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataRawResponse.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataRawResponse.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataRawResponse.java
index 8dd189a..a3de84f 100644
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataRawResponse.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataRawResponse.java
@@ -18,6 +18,8 @@
*/
package org.apache.olingo.client.api.communication.response;
+import org.apache.olingo.commons.api.data.ResWrap;
+
/**
* This interface represents a generic OData response.
*/
@@ -29,5 +31,5 @@ public interface ODataRawResponse extends ODataResponse {
* @param reference an OData domain object class reference
* @return response body parsed as the given reference, if available, <tt>null</tt> otherwise
*/
- <T> T getBodyAs(final Class<T> reference);
+ <T> ResWrap<T> getBodyAs(final Class<T> reference);
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15e7718a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataResponse.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataResponse.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataResponse.java
index 7da07ec..1538ad3 100644
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataResponse.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataResponse.java
@@ -19,7 +19,6 @@
package org.apache.olingo.client.api.communication.response;
import java.io.InputStream;
-import java.net.URI;
import java.util.Collection;
import java.util.Map;
import org.apache.http.HttpResponse;
@@ -59,31 +58,7 @@ public interface ODataResponse {
*
* @return ETag header value, if provided
*/
- String getEtag();
-
- /**
- * The context URL describes the content of the payload. It consists of the canonical metadata document URL and a
- * fragment identifying the relevant portion of the metadata document.
- * <br />
- * Request payloads generally do not require context URLs as the type of the payload can generally be determined from
- * the request URL.
- * <br />
- * For details on how the context URL is used to describe a payload, see the relevant sections in the particular
- * format.
- *
- * @return context URL.
- */
- URI getContextURL();
-
- /**
- * An ETag header MAY also be returned on a metadata document request or service document request to allow the client
- * subsequently to make a conditional request for the metadata or service document. Clients can also compare the value
- * of the ETag header returned from a metadata document request to the metadata ETag returned in a response in order
- * to verify the version of the metadata used to generate that response.
- *
- * @return metadata ETag.
- */
- String getMetadataETag();
+ String getETag();
/**
* Gets the content type.
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15e7718a/lib/client-api/src/main/java/org/apache/olingo/client/api/domain/ODataEntitySetIterator.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/domain/ODataEntitySetIterator.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/domain/ODataEntitySetIterator.java
index 107816f..8002845 100644
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/domain/ODataEntitySetIterator.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/domain/ODataEntitySetIterator.java
@@ -31,16 +31,17 @@ import org.apache.commons.lang3.StringUtils;
import org.apache.olingo.client.api.CommonODataClient;
import org.apache.olingo.commons.api.Constants;
import org.apache.olingo.commons.api.data.Entry;
-import org.apache.olingo.commons.api.format.ODataPubFormat;
+import org.apache.olingo.commons.api.data.ResWrap;
import org.apache.olingo.commons.api.domain.CommonODataEntity;
import org.apache.olingo.commons.api.domain.CommonODataEntitySet;
+import org.apache.olingo.commons.api.format.ODataPubFormat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* OData entity set iterator class.
* <br/>
- * <b>Please don't forget to call the <tt>close()>/<tt> method when not needed any more.</b>
+ * <b>Please don't forget to call the <tt>close()>/</tt> method when not needed any more.</b>
*
* @param <E> concrete ODataEntity implementation
* @param <ES> concrete ODataEntitySet implementation
@@ -61,7 +62,7 @@ public class ODataEntitySetIterator<ES extends CommonODataEntitySet, E extends C
private final ODataPubFormat format;
- private Entry cached;
+ private ResWrap<Entry> cached;
private ES entitySet;
@@ -78,7 +79,7 @@ public class ODataEntitySetIterator<ES extends CommonODataEntitySet, E extends C
* @param stream source stream.
* @param format OData format.
*/
- public ODataEntitySetIterator(final CommonODataClient odataClient, final InputStream stream,
+ public ODataEntitySetIterator(final CommonODataClient<?> odataClient, final InputStream stream,
final ODataPubFormat format) {
this.odataClient = odataClient;
@@ -171,10 +172,10 @@ public class ODataEntitySetIterator<ES extends CommonODataEntitySet, E extends C
return entitySet.getNext();
}
- private Entry nextJsonEntryFromFeed(final InputStream input, final OutputStream osFeed) {
+ private ResWrap<Entry> nextJsonEntryFromFeed(final InputStream input, final OutputStream osFeed) {
final ByteArrayOutputStream entry = new ByteArrayOutputStream();
- Entry jsonEntry = null;
+ ResWrap<Entry> jsonEntry = null;
try {
int c;
@@ -209,7 +210,7 @@ public class ODataEntitySetIterator<ES extends CommonODataEntitySet, E extends C
if (c >= 0) {
jsonEntry = odataClient.getDeserializer().toEntry(
- new ByteArrayInputStream(entry.toByteArray()), ODataPubFormat.JSON).getObject();
+ new ByteArrayInputStream(entry.toByteArray()), ODataPubFormat.JSON);
}
} else {
while ((c = input.read()) >= 0) {
@@ -230,10 +231,12 @@ public class ODataEntitySetIterator<ES extends CommonODataEntitySet, E extends C
* @param format de-serialize as AtomFeed or JSONFeed
* @return de-serialized entity set.
*/
- private Entry nextAtomEntryFromFeed(final InputStream input, final OutputStream osFeed, final String namespaces) {
+ private ResWrap<Entry> nextAtomEntryFromFeed(
+ final InputStream input, final OutputStream osFeed, final String namespaces) {
+
final ByteArrayOutputStream entry = new ByteArrayOutputStream();
- Entry atomEntry = null;
+ ResWrap<Entry> atomEntry = null;
try {
if (consume(input, "<entry>", osFeed, false) >= 0) {
@@ -243,7 +246,7 @@ public class ODataEntitySetIterator<ES extends CommonODataEntitySet, E extends C
if (consume(input, "</entry>", entry, true) >= 0) {
atomEntry = odataClient.getDeserializer().
- toEntry(new ByteArrayInputStream(entry.toByteArray()), ODataPubFormat.ATOM).getObject();
+ toEntry(new ByteArrayInputStream(entry.toByteArray()), ODataPubFormat.ATOM);
}
}
} catch (Exception e) {
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15e7718a/lib/client-api/src/main/java/org/apache/olingo/client/api/op/ClientODataDeserializer.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/op/ClientODataDeserializer.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/op/ClientODataDeserializer.java
index 24b6e60..9bca91a 100644
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/op/ClientODataDeserializer.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/op/ClientODataDeserializer.java
@@ -21,7 +21,7 @@ package org.apache.olingo.client.api.op;
import java.io.InputStream;
import org.apache.olingo.client.api.data.ServiceDocument;
import org.apache.olingo.client.api.edm.xml.XMLMetadata;
-import org.apache.olingo.commons.api.data.Container;
+import org.apache.olingo.commons.api.data.ResWrap;
import org.apache.olingo.commons.api.format.ODataFormat;
import org.apache.olingo.commons.api.op.CommonODataDeserializer;
@@ -36,5 +36,5 @@ public interface ClientODataDeserializer extends CommonODataDeserializer {
* @param format OData service document format.
* @return <tt>ServiceDocument</tt> object.
*/
- Container<ServiceDocument> toServiceDocument(InputStream input, ODataFormat format);
+ ResWrap<ServiceDocument> toServiceDocument(InputStream input, ODataFormat format);
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15e7718a/lib/client-api/src/main/java/org/apache/olingo/client/api/op/CommonODataBinder.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/op/CommonODataBinder.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/op/CommonODataBinder.java
index 0d8da52..acb08ae 100644
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/op/CommonODataBinder.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/op/CommonODataBinder.java
@@ -19,12 +19,12 @@
package org.apache.olingo.client.api.op;
import java.io.Serializable;
-import java.net.URI;
import org.apache.olingo.commons.api.data.Entry;
import org.apache.olingo.commons.api.data.Feed;
import org.apache.olingo.commons.api.data.Link;
import org.apache.olingo.commons.api.data.Property;
import org.apache.olingo.client.api.data.ServiceDocument;
+import org.apache.olingo.commons.api.data.ResWrap;
import org.apache.olingo.commons.api.domain.CommonODataEntity;
import org.apache.olingo.commons.api.domain.CommonODataEntitySet;
import org.apache.olingo.commons.api.domain.ODataLink;
@@ -90,41 +90,23 @@ public interface CommonODataBinder extends Serializable {
* Gets <tt>ODataEntitySet</tt> from the given feed resource.
*
* @param resource feed resource.
- * @return <tt>ODataEntitySet</tt> object.
+ * @return {@link CommonODataEntitySet} object.
*/
- CommonODataEntitySet getODataEntitySet(Feed resource);
-
- /**
- * Gets <tt>ODataEntitySet</tt> from the given feed resource.
- *
- * @param resource feed resource.
- * @param defaultBaseURI default base URI.
- * @return <tt>ODataEntitySet</tt> object.
- */
- CommonODataEntitySet getODataEntitySet(Feed resource, URI defaultBaseURI);
-
- /**
- * Gets <tt>ODataEntity</tt> from the given entry resource.
- *
- * @param resource entry resource.
- * @return <tt>ODataEntity</tt> object.
- */
- CommonODataEntity getODataEntity(Entry resource);
+ CommonODataEntitySet getODataEntitySet(ResWrap<Feed> resource);
/**
* Gets <tt>ODataEntity</tt> from the given entry resource.
*
* @param resource entry resource.
- * @param defaultBaseURI default base URI.
- * @return <tt>ODataEntity</tt> object.
+ * @return {@link CommonODataEntity} object.
*/
- CommonODataEntity getODataEntity(Entry resource, URI defaultBaseURI);
+ CommonODataEntity getODataEntity(ResWrap<Entry> resource);
/**
* Gets an <tt>ODataProperty</tt> from the given property resource.
*
- * @param property property resource.
- * @return <tt>ODataProperty</tt> object.
+ * @param resource property resource.
+ * @return {@link CommonODataProperty} object.
*/
- CommonODataProperty getODataProperty(Property property);
+ CommonODataProperty getODataProperty(ResWrap<Property> resource);
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15e7718a/lib/client-api/src/main/java/org/apache/olingo/client/api/op/CommonODataReader.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/op/CommonODataReader.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/op/CommonODataReader.java
index 923ac23..0f1335a 100644
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/op/CommonODataReader.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/op/CommonODataReader.java
@@ -22,7 +22,7 @@ import java.io.InputStream;
import java.io.Serializable;
import java.util.List;
import org.apache.olingo.client.api.edm.xml.Schema;
-import org.apache.olingo.commons.api.data.Container;
+import org.apache.olingo.commons.api.data.ResWrap;
import org.apache.olingo.commons.api.domain.ODataError;
import org.apache.olingo.commons.api.domain.CommonODataEntity;
import org.apache.olingo.commons.api.domain.CommonODataEntitySet;
@@ -112,5 +112,5 @@ public interface CommonODataReader extends Serializable {
* @param reference reference.
* @return read object.
*/
- <T> Container<T> read(InputStream src, String format, Class<T> reference);
+ <T> ResWrap<T> read(InputStream src, String format, Class<T> reference);
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15e7718a/lib/client-api/src/main/java/org/apache/olingo/client/api/op/v3/ODataBinder.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/op/v3/ODataBinder.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/op/v3/ODataBinder.java
index 52cb625..92d3061 100644
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/op/v3/ODataBinder.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/op/v3/ODataBinder.java
@@ -18,13 +18,13 @@
*/
package org.apache.olingo.client.api.op.v3;
-import java.net.URI;
import org.apache.olingo.commons.api.data.v3.LinkCollection;
import org.apache.olingo.client.api.domain.v3.ODataLinkCollection;
import org.apache.olingo.client.api.op.CommonODataBinder;
import org.apache.olingo.commons.api.data.Entry;
import org.apache.olingo.commons.api.data.Feed;
import org.apache.olingo.commons.api.data.Property;
+import org.apache.olingo.commons.api.data.ResWrap;
import org.apache.olingo.commons.api.domain.v3.ODataEntity;
import org.apache.olingo.commons.api.domain.v3.ODataEntitySet;
import org.apache.olingo.commons.api.domain.v3.ODataProperty;
@@ -32,19 +32,13 @@ import org.apache.olingo.commons.api.domain.v3.ODataProperty;
public interface ODataBinder extends CommonODataBinder {
@Override
- ODataEntitySet getODataEntitySet(Feed resource);
+ ODataEntitySet getODataEntitySet(ResWrap<Feed> resource);
@Override
- ODataEntitySet getODataEntitySet(Feed resource, URI defaultBaseURI);
+ ODataEntity getODataEntity(ResWrap<Entry> resource);
@Override
- ODataEntity getODataEntity(Entry resource);
-
- @Override
- ODataEntity getODataEntity(Entry resource, URI defaultBaseURI);
-
- @Override
- ODataProperty getODataProperty(Property property);
+ ODataProperty getODataProperty(ResWrap<Property> resource);
/**
* Gets <tt>ODataLinkCollection</tt> from the given link collection resource.
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15e7718a/lib/client-api/src/main/java/org/apache/olingo/client/api/op/v3/ODataDeserializer.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/op/v3/ODataDeserializer.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/op/v3/ODataDeserializer.java
index bc16b74..ff559a1 100644
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/op/v3/ODataDeserializer.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/op/v3/ODataDeserializer.java
@@ -20,7 +20,7 @@ package org.apache.olingo.client.api.op.v3;
import java.io.InputStream;
import org.apache.olingo.client.api.op.ClientODataDeserializer;
-import org.apache.olingo.commons.api.data.Container;
+import org.apache.olingo.commons.api.data.ResWrap;
import org.apache.olingo.commons.api.data.v3.LinkCollection;
import org.apache.olingo.commons.api.format.ODataFormat;
@@ -33,6 +33,6 @@ public interface ODataDeserializer extends ClientODataDeserializer {
* @param format OData format.
* @return de-serialized links.
*/
- Container<LinkCollection> toLinkCollection(InputStream input, ODataFormat format);
+ ResWrap<LinkCollection> toLinkCollection(InputStream input, ODataFormat format);
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15e7718a/lib/client-api/src/main/java/org/apache/olingo/client/api/op/v4/ODataBinder.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/op/v4/ODataBinder.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/op/v4/ODataBinder.java
index d2805bb..9c84a8c 100644
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/op/v4/ODataBinder.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/op/v4/ODataBinder.java
@@ -18,11 +18,11 @@
*/
package org.apache.olingo.client.api.op.v4;
-import java.net.URI;
import org.apache.olingo.client.api.op.CommonODataBinder;
import org.apache.olingo.commons.api.data.Entry;
import org.apache.olingo.commons.api.data.Feed;
import org.apache.olingo.commons.api.data.Property;
+import org.apache.olingo.commons.api.data.ResWrap;
import org.apache.olingo.commons.api.domain.v4.ODataEntity;
import org.apache.olingo.commons.api.domain.v4.ODataEntitySet;
import org.apache.olingo.commons.api.domain.v4.ODataProperty;
@@ -30,19 +30,11 @@ import org.apache.olingo.commons.api.domain.v4.ODataProperty;
public interface ODataBinder extends CommonODataBinder {
@Override
- ODataEntitySet getODataEntitySet(Feed resource);
+ ODataEntitySet getODataEntitySet(ResWrap<Feed> resource);
@Override
- ODataEntitySet getODataEntitySet(Feed resource, URI defaultBaseURI);
+ ODataEntity getODataEntity(ResWrap<Entry> resource);
@Override
- ODataEntity getODataEntity(Entry resource);
-
- @Override
- ODataEntity getODataEntity(Entry resource, URI defaultBaseURI);
-
- @Override
- ODataProperty getODataProperty(Property property);
-
- ODataProperty getODataProperty(Property property, URI base);
+ ODataProperty getODataProperty(ResWrap<Property> resource);
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15e7718a/lib/client-api/src/main/java/org/apache/olingo/client/api/v3/EdmEnabledODataClient.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/v3/EdmEnabledODataClient.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/v3/EdmEnabledODataClient.java
new file mode 100644
index 0000000..379c8b0
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/v3/EdmEnabledODataClient.java
@@ -0,0 +1,26 @@
+/*
+ * 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.client.api.v3;
+
+import org.apache.olingo.client.api.CommonEdmEnabledODataClient;
+import org.apache.olingo.client.api.communication.request.cud.v3.UpdateType;
+
+public interface EdmEnabledODataClient extends CommonEdmEnabledODataClient<UpdateType>, ODataClient {
+
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15e7718a/lib/client-api/src/main/java/org/apache/olingo/client/api/v4/EdmEnabledODataClient.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/v4/EdmEnabledODataClient.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/v4/EdmEnabledODataClient.java
new file mode 100644
index 0000000..abd341d
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/v4/EdmEnabledODataClient.java
@@ -0,0 +1,26 @@
+/*
+ * 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.client.api.v4;
+
+import org.apache.olingo.client.api.CommonEdmEnabledODataClient;
+import org.apache.olingo.client.api.communication.request.cud.v4.UpdateType;
+
+public interface EdmEnabledODataClient extends CommonEdmEnabledODataClient<UpdateType>, ODataClient {
+
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15e7718a/lib/client-core/src/main/java/org/apache/olingo/client/core/ODataClientFactory.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/ODataClientFactory.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/ODataClientFactory.java
index e0fcd76..a9c87ed 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/ODataClientFactory.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/ODataClientFactory.java
@@ -18,16 +18,32 @@
*/
package org.apache.olingo.client.core;
+import org.apache.olingo.commons.api.format.ODataPubFormat;
+
public final class ODataClientFactory {
public static org.apache.olingo.client.api.v3.ODataClient getV3() {
return new org.apache.olingo.client.core.v3.ODataClientImpl();
}
+ public static org.apache.olingo.client.api.v3.EdmEnabledODataClient getEdmEnabledV3(final String serviceRoot) {
+ final org.apache.olingo.client.api.v3.EdmEnabledODataClient instance =
+ new org.apache.olingo.client.core.v3.EdmEnabledODataClientImpl(serviceRoot);
+ instance.getConfiguration().setDefaultPubFormat(ODataPubFormat.JSON);
+ return instance;
+ }
+
public static org.apache.olingo.client.api.v4.ODataClient getV4() {
return new org.apache.olingo.client.core.v4.ODataClientImpl();
}
+ public static org.apache.olingo.client.api.v4.EdmEnabledODataClient getEdmEnabledV4(final String serviceRoot) {
+ final org.apache.olingo.client.api.v4.EdmEnabledODataClient instance =
+ new org.apache.olingo.client.core.v4.EdmEnabledODataClientImpl(serviceRoot);
+ instance.getConfiguration().setDefaultPubFormat(ODataPubFormat.JSON);
+ return instance;
+ }
+
private ODataClientFactory() {
// empty constructory for static utility class
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15e7718a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractODataRequest.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractODataRequest.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractODataRequest.java
index 8bc4d1c..c8185d4 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractODataRequest.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractODataRequest.java
@@ -364,6 +364,8 @@ public abstract class AbstractODataRequest<T extends Format> extends AbstractReq
* @return HttpReponse object.
*/
protected HttpResponse doExecute() {
+ checkRequest(odataClient, request);
+
// Set Content-Type and Accept headers with default values, if not yet set
if (StringUtils.isBlank(odataHeaders.getHeader(HeaderName.contentType))) {
setContentType(getContentType());
@@ -390,7 +392,7 @@ public abstract class AbstractODataRequest<T extends Format> extends AbstractReq
}
}
- final HttpResponse response;
+ HttpResponse response;
try {
response = this.httpClient.execute(this.request);
} catch (IOException e) {
@@ -400,7 +402,7 @@ public abstract class AbstractODataRequest<T extends Format> extends AbstractReq
throw new HttpClientException(e);
}
- checkForResponse(odataClient, response, getAccept());
+ checkResponse(odataClient, response, getAccept());
return response;
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15e7718a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractRequest.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractRequest.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractRequest.java
index 25514b8..5779e08 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractRequest.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractRequest.java
@@ -18,6 +18,8 @@ package org.apache.olingo.client.core.communication.request;
import java.io.IOException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
+import org.apache.http.client.methods.HttpUriRequest;
+import org.apache.olingo.client.api.CommonEdmEnabledODataClient;
import org.apache.olingo.client.api.CommonODataClient;
import org.apache.olingo.client.api.communication.ODataClientErrorException;
import org.apache.olingo.client.api.communication.ODataServerErrorException;
@@ -50,8 +52,21 @@ public abstract class AbstractRequest {
return error;
}
- protected <C extends CommonODataClient<?>> void checkForResponse(
- final C odataClient, final HttpResponse response, final String accept) {
+ protected void checkRequest(final CommonODataClient<?> odataClient, final HttpUriRequest request) {
+ // If using and Edm enabled client, checks that the cached service root matches the request URI
+ if (odataClient instanceof CommonEdmEnabledODataClient
+ && !request.getURI().toASCIIString().startsWith(
+ ((CommonEdmEnabledODataClient) odataClient).getServiceRoot())) {
+
+ throw new IllegalArgumentException(
+ String.format("The current request URI %s does not match the configured service root %s",
+ request.getURI().toASCIIString(),
+ ((CommonEdmEnabledODataClient) odataClient).getServiceRoot()));
+ }
+ }
+
+ protected void checkResponse(
+ final CommonODataClient<?> odataClient, final HttpResponse response, final String accept) {
if (response.getStatusLine().getStatusCode() >= 500) {
throw new ODataServerErrorException(response.getStatusLine());
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15e7718a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataEntityCreateRequestImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataEntityCreateRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataEntityCreateRequestImpl.java
index 7f9ad36..19ed949 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataEntityCreateRequestImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataEntityCreateRequestImpl.java
@@ -33,7 +33,7 @@ import org.apache.olingo.client.api.http.HttpMethod;
import org.apache.olingo.client.core.uri.URIUtils;
import org.apache.olingo.client.core.communication.request.AbstractODataBasicRequest;
import org.apache.olingo.client.core.communication.response.AbstractODataResponse;
-import org.apache.olingo.commons.api.data.Container;
+import org.apache.olingo.commons.api.data.ResWrap;
import org.apache.olingo.commons.api.data.Entry;
/**
@@ -119,10 +119,10 @@ public class ODataEntityCreateRequestImpl<E extends CommonODataEntity>
public E getBody() {
if (entity == null) {
try {
- final Container<Entry> container = odataClient.getDeserializer().toEntry(getRawResponse(),
- ODataPubFormat.fromString(getAccept()));
-
- entity = (E) odataClient.getBinder().getODataEntity(extractFromContainer(container));
+ final ResWrap<Entry> resource = odataClient.getDeserializer().
+ toEntry(getRawResponse(), ODataPubFormat.fromString(getAccept()));
+
+ entity = (E) odataClient.getBinder().getODataEntity(resource);
} finally {
this.close();
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15e7718a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataEntityUpdateRequestImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataEntityUpdateRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataEntityUpdateRequestImpl.java
index 67be0d4..1134d79 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataEntityUpdateRequestImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataEntityUpdateRequestImpl.java
@@ -33,7 +33,7 @@ import org.apache.olingo.client.api.http.HttpMethod;
import org.apache.olingo.client.core.uri.URIUtils;
import org.apache.olingo.client.core.communication.request.AbstractODataBasicRequest;
import org.apache.olingo.client.core.communication.response.AbstractODataResponse;
-import org.apache.olingo.commons.api.data.Container;
+import org.apache.olingo.commons.api.data.ResWrap;
import org.apache.olingo.commons.api.data.Entry;
/**
@@ -124,10 +124,10 @@ public class ODataEntityUpdateRequestImpl<E extends CommonODataEntity>
public E getBody() {
if (entity == null) {
try {
- final Container<Entry> container = odataClient.getDeserializer().toEntry(getRawResponse(),
- ODataPubFormat.fromString(getAccept()));
+ final ResWrap<Entry> resource = odataClient.getDeserializer().
+ toEntry(getRawResponse(), ODataPubFormat.fromString(getAccept()));
- entity = (E) odataClient.getBinder().getODataEntity(extractFromContainer(container));
+ entity = (E) odataClient.getBinder().getODataEntity(resource);
} finally {
this.close();
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15e7718a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataPropertyUpdateRequestImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataPropertyUpdateRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataPropertyUpdateRequestImpl.java
index 26250dc..81e1dd4 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataPropertyUpdateRequestImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataPropertyUpdateRequestImpl.java
@@ -33,7 +33,7 @@ import org.apache.olingo.client.api.http.HttpMethod;
import org.apache.olingo.client.core.uri.URIUtils;
import org.apache.olingo.client.core.communication.request.AbstractODataBasicRequest;
import org.apache.olingo.client.core.communication.response.AbstractODataResponse;
-import org.apache.olingo.commons.api.data.Container;
+import org.apache.olingo.commons.api.data.ResWrap;
import org.apache.olingo.commons.api.data.Property;
/**
@@ -118,10 +118,10 @@ public class ODataPropertyUpdateRequestImpl extends AbstractODataBasicRequest<OD
public CommonODataProperty getBody() {
if (property == null) {
try {
- final Container<Property> container = odataClient.getDeserializer().toProperty(getRawResponse(),
- ODataFormat.fromString(getAccept()));
+ final ResWrap<Property> resource = odataClient.getDeserializer().
+ toProperty(getRawResponse(), ODataFormat.fromString(getAccept()));
- property = odataClient.getBinder().getODataProperty(extractFromContainer(container));
+ property = odataClient.getBinder().getODataProperty(resource);
} finally {
this.close();
}