[OLINGO-663] clean-up

Change-Id: Id1359ca3243e42d83ce0bd3057da3477850730e6

Signed-off-by: Christian Amend <chrisam@apache.org>
This commit is contained in:
Klaus Straubinger 2015-06-02 15:14:57 +02:00 committed by Christian Amend
parent a4913636dc
commit c65ef5e9e7
23 changed files with 463 additions and 278 deletions

View File

@ -212,8 +212,7 @@ public class SystemQueryOptionITCase extends AbstractBaseTestITCase {
// Check initial next link format
URI nextLink = response.getBody().getNext();
assertEquals("http://localhost:9080/odata-server-tecsvc/odata.svc/ESServerSidePaging?%24skiptoken=1", nextLink
.toASCIIString());
assertEquals(SERVICE_URI + "/ESServerSidePaging?%24skiptoken=1", nextLink.toASCIIString());
// Check subsequent next links
response = client.getRetrieveRequestFactory()
@ -221,8 +220,7 @@ public class SystemQueryOptionITCase extends AbstractBaseTestITCase {
.execute();
nextLink = response.getBody().getNext();
assertEquals("http://localhost:9080/odata-server-tecsvc/odata.svc/ESServerSidePaging?%24skiptoken=2", nextLink
.toASCIIString());
assertEquals(SERVICE_URI + "/ESServerSidePaging?%24skiptoken=2", nextLink.toASCIIString());
}
@Test
@ -239,7 +237,7 @@ public class SystemQueryOptionITCase extends AbstractBaseTestITCase {
// Check initial next link format
URI nextLink = response.getBody().getNext();
assertEquals("http://localhost:9080/odata-server-tecsvc/odata.svc/ESServerSidePaging?%24count=true&%24skiptoken=1",
assertEquals(SERVICE_URI + "/ESServerSidePaging?%24count=true&%24skiptoken=1",
nextLink.toASCIIString());
int token = 1;
@ -253,10 +251,8 @@ public class SystemQueryOptionITCase extends AbstractBaseTestITCase {
nextLink = response.getBody().getNext();
if (nextLink != null) {
assertEquals(
"http://localhost:9080/odata-server-tecsvc/odata.svc/ESServerSidePaging?%24count=true&%24skiptoken="
+ token,
nextLink.toASCIIString());
assertEquals(SERVICE_URI + "/ESServerSidePaging?%24count=true&%24skiptoken=" + token,
nextLink.toASCIIString());
}
}

View File

@ -1,29 +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.client.api.communication.response;
/**
* This interface defines the response to an OData link operation request.
*
* @see org.apache.olingo.client.api.communication.request.cud.v3.ODataLinkCreateRequest
* @see org.apache.olingo.client.api.communication.request.cud.v3.ODataLinkUpdateRequest
*/
public interface ODataLinkOperationResponse extends ODataResponse {
//No additional methods needed for now.
}

View File

@ -0,0 +1,74 @@
/*
* 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.server.api;
import java.util.Collection;
/**
* Information about the values of an ETag-relevant HTTP header.
*/
public class ETagInformation {
private final boolean all;
private final Collection<String> eTags;
public ETagInformation(final boolean all, final Collection<String> eTags) {
this.all = all;
this.eTags = eTags;
}
/**
* Gets the information whether the values contain "*".
*/
public boolean isAll() {
return all;
}
/**
* Gets the collection of ETag values found.
* It is empty if {@link #isAll()} returns <code>true</code>.
*/
public Collection<String> getETags() {
return eTags;
}
/**
* <p>Checks whether a given ETag value is matched by this ETag information,
* using weak comparison as described in
* <a href="https://www.ietf.org/rfc/rfc7232.txt">RFC 7232</a>, section 2.3.2.</p>
* <p>If the given value is <code>null</code>, or if this ETag information
* does not contain anything, the result is <code>false</code>.</p>
* @param eTag the ETag value to match
* @return a boolean match result
*/
public boolean isMatchedBy(final String eTag) {
if (eTag == null) {
return false;
} else if (all) {
return true;
} else {
for (final String candidate : eTags) {
if ((eTag.startsWith("W/") ? eTag.substring(2) : eTag)
.equals(candidate.startsWith("W/") ? candidate.substring(2) : candidate)) {
return true;
}
}
return false;
}
}
}

View File

@ -23,13 +23,13 @@ import java.util.Collection;
/**
* Information about the values of an ETag-relevant HTTP header.
*/
public class EtagInformation {
public class ETagInformation {
private final boolean all;
private final Collection<String> etags;
private final Collection<String> eTags;
public EtagInformation(final boolean all, final Collection<String> etags) {
public ETagInformation(final boolean all, final Collection<String> eTags) {
this.all = all;
this.etags = etags;
this.eTags = eTags;
}
/**
@ -43,8 +43,8 @@ public class EtagInformation {
* Gets the collection of ETag values found.
* It is empty if {@link #isAll()} returns <code>true</code>.
*/
public Collection<String> getEtags() {
return etags;
public Collection<String> getETags() {
return eTags;
}
/**
@ -53,17 +53,17 @@ public class EtagInformation {
* <a href="https://www.ietf.org/rfc/rfc7232.txt">RFC 7232</a>, section 2.3.2.</p>
* <p>If the given value is <code>null</code>, or if this ETag information
* does not contain anything, the result is <code>false</code>.</p>
* @param etag the ETag value to match
* @param eTag the ETag value to match
* @return a boolean match result
*/
public boolean isMatchedBy(final String etag) {
if (etag == null) {
public boolean isMatchedBy(final String eTag) {
if (eTag == null) {
return false;
} else if (all) {
return true;
} else {
for (final String candidate : etags) {
if ((etag.startsWith("W/") ? etag.substring(2) : etag)
for (final String candidate : eTags) {
if ((eTag.startsWith("W/") ? eTag.substring(2) : eTag)
.equals(candidate.startsWith("W/") ? candidate.substring(2) : candidate)) {
return true;
}

View File

@ -118,11 +118,11 @@ public abstract class OData {
public abstract EdmPrimitiveType createPrimitiveTypeInstance(EdmPrimitiveTypeKind kind);
/**
* Creates Etag information from the values of a HTTP header
* Creates ETag information from the values of a HTTP header
* containing a list of entity tags or a single star character, i.e.,
* <code>If-Match</code> and <code>If-None-Match</code>.
* @param values the collection of header values
* @return an {@link EtagInformation} instance
* @return an {@link ETagInformation} instance
*/
public abstract EtagInformation createEtagInformation(final Collection<String> values);
public abstract ETagInformation createETagInformation(final Collection<String> values);
}

View File

@ -0,0 +1,86 @@
/*
* 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.server.core;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* <p>Parses the values of HTTP header fields that contain a list of entity tags or a
* single star character, i.e., <code>If-Match</code> and <code>If-None-Match</code>.</p>
* <p>See <a href="https://www.ietf.org/rfc/rfc7232.txt">RFC 7232</a> for details;
* there the following grammar is defined:</p>
* <pre>
* If-Match = "*" / 1#entity-tag
* If-None-Match = "*" / 1#entity-tag
* entity-tag = [ weak ] opaque-tag
* weak = %x57.2F ; "W/", case-sensitive
* opaque-tag = DQUOTE *etagc DQUOTE
* etagc = %x21 / %x23-7E / %x80-FF
* </pre>
* <p>Values with illegal syntax do not contribute to the result but no exception is thrown.</p>
*/
public class ETagParser {
private static final Pattern ETAG = Pattern.compile("\\s*(,\\s*)+|((?:W/)?\"[!#-~\\x80-\\xFF]*\")");
protected static Collection<String> parse(final Collection<String> values) {
if (values == null) {
return Collections.<String> emptySet();
}
Set<String> result = new HashSet<String>();
for (final String value : values) {
final Collection<String> part = parse(value);
if (part.size() == 1 && part.iterator().next().equals("*")) {
return part;
} else {
result.addAll(part);
}
}
return result;
}
private static Collection<String> parse(final String value) {
if (value.trim().equals("*")) {
return Collections.singleton("*");
} else {
Set<String> result = new HashSet<String>();
String separator = "";
int start = 0;
Matcher matcher = ETAG.matcher(value.trim());
while (matcher.find() && matcher.start() == start) {
start = matcher.end();
if (matcher.group(1) != null) {
separator = matcher.group(1);
} else if (separator != null) {
result.add(matcher.group(2));
separator = null;
} else {
return Collections.<String> emptySet();
}
}
return matcher.hitEnd() ? result : Collections.<String> emptySet();
}
}
}

View File

@ -40,7 +40,7 @@ import java.util.regex.Pattern;
* </pre>
* <p>Values with illegal syntax do not contribute to the result but no exception is thrown.</p>
*/
public class EtagParser {
public class ETagParser {
private static final Pattern ETAG = Pattern.compile("\\s*(,\\s*)+|((?:W/)?\"[!#-~\\x80-\\xFF]*\")");

View File

@ -96,7 +96,7 @@ public class ODataHandler {
} catch (PreconditionRequiredException e) {
ODataServerError serverError = ODataExceptionHelper.createServerErrorObject(e, null);
handleException(request, response, serverError);
}catch (ODataHandlerException e) {
} catch (ODataHandlerException e) {
ODataServerError serverError = ODataExceptionHelper.createServerErrorObject(e, null);
handleException(request, response, serverError);
} catch (ODataApplicationException e) {
@ -175,7 +175,7 @@ public class ODataHandler {
public void register(final CustomContentTypeSupport customContentTypeSupport) {
this.customContentTypeSupport = customContentTypeSupport;
}
public CustomContentTypeSupport getCustomContentTypeSupport() {
return customContentTypeSupport;
}

View File

@ -27,7 +27,7 @@ import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
import org.apache.olingo.commons.api.edm.provider.CsdlEdmProvider;
import org.apache.olingo.commons.api.format.ODataFormat;
import org.apache.olingo.commons.core.edm.primitivetype.EdmPrimitiveTypeFactory;
import org.apache.olingo.server.api.EtagInformation;
import org.apache.olingo.server.api.ETagInformation;
import org.apache.olingo.server.api.OData;
import org.apache.olingo.server.api.ODataHttpHandler;
import org.apache.olingo.server.api.ServiceMetadata;
@ -119,10 +119,10 @@ public class ODataImpl extends OData {
}
@Override
public EtagInformation createEtagInformation(final Collection<String> values) {
final Collection<String> etags = EtagParser.parse(values);
final boolean isAll = etags.size() == 1 && etags.iterator().next().equals("*");
return new EtagInformation(isAll,
isAll ? Collections.<String> emptySet() : Collections.unmodifiableCollection(etags));
public ETagInformation createETagInformation(final Collection<String> values) {
final Collection<String> eTags = ETagParser.parse(values);
final boolean isAll = eTags.size() == 1 && eTags.iterator().next().equals("*");
return new ETagInformation(isAll,
isAll ? Collections.<String> emptySet() : Collections.unmodifiableCollection(eTags));
}
}

View File

@ -24,7 +24,9 @@ public class PreconditionRequiredException extends ODataTranslatedException {
private static final long serialVersionUID = -8112658467394158700L;
public static enum MessageKeys implements MessageKey {
/** no parameter */
MISSING_HEADER,
/** no parameter */
INVALID_URI;
@Override
@ -39,8 +41,7 @@ public class PreconditionRequiredException extends ODataTranslatedException {
}
public PreconditionRequiredException(final String developmentMessage, final Throwable cause,
final MessageKey messageKey,
final String... parameters) {
final MessageKey messageKey, final String... parameters) {
super(developmentMessage, cause, messageKey, parameters);
}

View File

@ -28,10 +28,10 @@ import org.apache.olingo.server.api.processor.BatchProcessor;
import org.apache.olingo.server.core.ODataHandler;
import org.apache.olingo.server.core.deserializer.batch.BatchParserCommon;
public class BatchFascadeImpl implements BatchFacade {
public class BatchFacadeImpl implements BatchFacade {
private final BatchPartHandler partHandler;
public BatchFascadeImpl(final ODataHandler oDataHandler, final ODataRequest request,
public BatchFacadeImpl(final ODataHandler oDataHandler, final ODataRequest request,
final BatchProcessor batchProcessor,
final boolean isStrict) {
partHandler = new BatchPartHandler(oDataHandler, batchProcessor, this);

View File

@ -45,7 +45,7 @@ public class BatchHandler {
throws DeserializerException, SerializerException {
validateRequest(request);
final BatchFacade operation = new BatchFascadeImpl(oDataHandler, request, batchProcessor, isStrict);
final BatchFacade operation = new BatchFacadeImpl(oDataHandler, request, batchProcessor, isStrict);
batchProcessor.processBatch(operation, request, response);
}

View File

@ -0,0 +1,131 @@
/*
* 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.server.core;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.hasItems;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import java.util.Arrays;
import java.util.Collections;
import org.apache.olingo.server.api.ETagInformation;
import org.apache.olingo.server.api.OData;
import org.junit.Test;
public class ETagParserTest {
private static final OData odata = OData.newInstance();
@Test
public void empty() {
final ETagInformation eTagInformation = odata.createETagInformation(null);
assertFalse(eTagInformation.isAll());
assertNotNull(eTagInformation.getETags());
assertTrue(eTagInformation.getETags().isEmpty());
}
@Test
public void loneStar() {
final ETagInformation eTagInformation = odata.createETagInformation(Collections.singleton("*"));
assertTrue(eTagInformation.isAll());
assertNotNull(eTagInformation.getETags());
assertTrue(eTagInformation.getETags().isEmpty());
}
@Test
public void starWins() {
final ETagInformation eTagInformation = odata.createETagInformation(Arrays.asList("\"ETag\"", "*"));
assertTrue(eTagInformation.isAll());
assertNotNull(eTagInformation.getETags());
assertTrue(eTagInformation.getETags().isEmpty());
}
@Test
public void starAsEtagAndEmptyEtag() {
final ETagInformation eTagInformation = odata.createETagInformation(
Collections.singleton("\"*\", \"\""));
assertFalse(eTagInformation.isAll());
assertNotNull(eTagInformation.getETags());
assertThat(eTagInformation.getETags().size(), equalTo(2));
assertThat(eTagInformation.getETags(), hasItems("\"*\"", "\"\""));
}
@Test
public void severalEtags() {
final ETagInformation eTagInformation = odata.createETagInformation(
Arrays.asList("\"ETag1\"", "\"ETag2\",, , ,W/\"ETag3\", ,"));
assertFalse(eTagInformation.isAll());
assertNotNull(eTagInformation.getETags());
assertThat(eTagInformation.getETags().size(), equalTo(3));
assertThat(eTagInformation.getETags(), hasItems("\"ETag1\"", "\"ETag2\"", "W/\"ETag3\""));
}
@Test
public void duplicateEtagValues() {
final ETagInformation eTagInformation = odata.createETagInformation(
Arrays.asList("\"ETag1\"", "\"ETag2\", W/\"ETag1\", \"ETag1\""));
assertFalse(eTagInformation.isAll());
assertNotNull(eTagInformation.getETags());
assertThat(eTagInformation.getETags().size(), equalTo(3));
assertThat(eTagInformation.getETags(), hasItems("\"ETag1\"", "\"ETag2\"", "W/\"ETag1\""));
}
@Test
public void specialCharacters() {
final ETagInformation eTagInformation = odata.createETagInformation(
Collections.singleton("\"!#$%&'()*+,-./:;<=>?@[]^_`{|}~¡\u00FF\", \"ETag2\""));
assertFalse(eTagInformation.isAll());
assertNotNull(eTagInformation.getETags());
assertThat(eTagInformation.getETags().size(), equalTo(2));
assertThat(eTagInformation.getETags(), hasItems(
"\"!#$%&'()*+,-./:;<=>?@[]^_`{|}~¡\u00FF\"", "\"ETag2\""));
}
@Test
public void wrongFormat() {
final ETagInformation eTagInformation = odata.createETagInformation(
Arrays.asList("\"ETag1\", ETag2", "w/\"ETag3\"", "W//\"ETag4\"", "W/ETag5",
"\"\"ETag6\"\"", " \"ETag7\"\"ETag7\" ", "\"ETag8\" \"ETag8\"",
"\"ETag 9\"", "\"ETag10\""));
assertFalse(eTagInformation.isAll());
assertNotNull(eTagInformation.getETags());
assertThat(eTagInformation.getETags().size(), equalTo(2));
assertThat(eTagInformation.getETags(), hasItems("\"ETag1\"", "\"ETag10\""));
}
@Test
public void match() {
assertFalse(odata.createETagInformation(Collections.<String> emptySet()).isMatchedBy("\"ETag\""));
assertFalse(odata.createETagInformation(Collections.singleton("\"ETag\"")).isMatchedBy(null));
assertTrue(odata.createETagInformation(Collections.singleton("\"ETag\"")).isMatchedBy("\"ETag\""));
assertTrue(odata.createETagInformation(Collections.singleton("*")).isMatchedBy("\"ETag\""));
assertTrue(odata.createETagInformation(Collections.singleton("\"ETag\"")).isMatchedBy("W/\"ETag\""));
assertTrue(odata.createETagInformation(Collections.singleton("W/\"ETag\"")).isMatchedBy("\"ETag\""));
assertFalse(odata.createETagInformation(Collections.singleton("\"ETag\"")).isMatchedBy("W/\"ETag2\""));
assertFalse(odata.createETagInformation(Collections.singleton("W/\"ETag\"")).isMatchedBy("\"ETag2\""));
assertTrue(odata.createETagInformation(Arrays.asList("\"ETag1\",\"ETag2\"", "\"ETag3\",\"ETag4\""))
.isMatchedBy("\"ETag4\""));
assertFalse(odata.createETagInformation(Arrays.asList("\"ETag1\",\"ETag2\"", "\"ETag3\",\"ETag4\""))
.isMatchedBy("\"ETag5\""));
}
}

View File

@ -28,104 +28,104 @@ import static org.junit.Assert.assertTrue;
import java.util.Arrays;
import java.util.Collections;
import org.apache.olingo.server.api.EtagInformation;
import org.apache.olingo.server.api.ETagInformation;
import org.apache.olingo.server.api.OData;
import org.junit.Test;
public class EtagParserTest {
public class ETagParserTest {
private static final OData odata = OData.newInstance();
@Test
public void empty() {
final EtagInformation etagInformation = odata.createEtagInformation(null);
assertFalse(etagInformation.isAll());
assertNotNull(etagInformation.getEtags());
assertTrue(etagInformation.getEtags().isEmpty());
final ETagInformation eTagInformation = odata.createETagInformation(null);
assertFalse(eTagInformation.isAll());
assertNotNull(eTagInformation.getETags());
assertTrue(eTagInformation.getETags().isEmpty());
}
@Test
public void loneStar() {
final EtagInformation etagInformation = odata.createEtagInformation(Collections.singleton("*"));
assertTrue(etagInformation.isAll());
assertNotNull(etagInformation.getEtags());
assertTrue(etagInformation.getEtags().isEmpty());
final ETagInformation eTagInformation = odata.createETagInformation(Collections.singleton("*"));
assertTrue(eTagInformation.isAll());
assertNotNull(eTagInformation.getETags());
assertTrue(eTagInformation.getETags().isEmpty());
}
@Test
public void starWins() {
final EtagInformation etagInformation = odata.createEtagInformation(Arrays.asList("\"ETag\"", "*"));
assertTrue(etagInformation.isAll());
assertNotNull(etagInformation.getEtags());
assertTrue(etagInformation.getEtags().isEmpty());
final ETagInformation eTagInformation = odata.createETagInformation(Arrays.asList("\"ETag\"", "*"));
assertTrue(eTagInformation.isAll());
assertNotNull(eTagInformation.getETags());
assertTrue(eTagInformation.getETags().isEmpty());
}
@Test
public void starAsEtagAndEmptyEtag() {
final EtagInformation etagInformation = odata.createEtagInformation(
final ETagInformation eTagInformation = odata.createETagInformation(
Collections.singleton("\"*\", \"\""));
assertFalse(etagInformation.isAll());
assertNotNull(etagInformation.getEtags());
assertThat(etagInformation.getEtags().size(), equalTo(2));
assertThat(etagInformation.getEtags(), hasItems("\"*\"", "\"\""));
assertFalse(eTagInformation.isAll());
assertNotNull(eTagInformation.getETags());
assertThat(eTagInformation.getETags().size(), equalTo(2));
assertThat(eTagInformation.getETags(), hasItems("\"*\"", "\"\""));
}
@Test
public void severalEtags() {
final EtagInformation etagInformation = odata.createEtagInformation(
final ETagInformation eTagInformation = odata.createETagInformation(
Arrays.asList("\"ETag1\"", "\"ETag2\",, , ,W/\"ETag3\", ,"));
assertFalse(etagInformation.isAll());
assertNotNull(etagInformation.getEtags());
assertThat(etagInformation.getEtags().size(), equalTo(3));
assertThat(etagInformation.getEtags(), hasItems("\"ETag1\"", "\"ETag2\"", "W/\"ETag3\""));
assertFalse(eTagInformation.isAll());
assertNotNull(eTagInformation.getETags());
assertThat(eTagInformation.getETags().size(), equalTo(3));
assertThat(eTagInformation.getETags(), hasItems("\"ETag1\"", "\"ETag2\"", "W/\"ETag3\""));
}
@Test
public void duplicateEtagValues() {
final EtagInformation etagInformation = odata.createEtagInformation(
final ETagInformation eTagInformation = odata.createETagInformation(
Arrays.asList("\"ETag1\"", "\"ETag2\", W/\"ETag1\", \"ETag1\""));
assertFalse(etagInformation.isAll());
assertNotNull(etagInformation.getEtags());
assertThat(etagInformation.getEtags().size(), equalTo(3));
assertThat(etagInformation.getEtags(), hasItems("\"ETag1\"", "\"ETag2\"", "W/\"ETag1\""));
assertFalse(eTagInformation.isAll());
assertNotNull(eTagInformation.getETags());
assertThat(eTagInformation.getETags().size(), equalTo(3));
assertThat(eTagInformation.getETags(), hasItems("\"ETag1\"", "\"ETag2\"", "W/\"ETag1\""));
}
@Test
public void specialCharacters() {
final EtagInformation etagInformation = odata.createEtagInformation(
final ETagInformation eTagInformation = odata.createETagInformation(
Collections.singleton("\"!#$%&'()*+,-./:;<=>?@[]^_`{|}~¡\u00FF\", \"ETag2\""));
assertFalse(etagInformation.isAll());
assertNotNull(etagInformation.getEtags());
assertThat(etagInformation.getEtags().size(), equalTo(2));
assertThat(etagInformation.getEtags(), hasItems(
assertFalse(eTagInformation.isAll());
assertNotNull(eTagInformation.getETags());
assertThat(eTagInformation.getETags().size(), equalTo(2));
assertThat(eTagInformation.getETags(), hasItems(
"\"!#$%&'()*+,-./:;<=>?@[]^_`{|}~¡\u00FF\"", "\"ETag2\""));
}
@Test
public void wrongFormat() {
final EtagInformation etagInformation = odata.createEtagInformation(
final ETagInformation eTagInformation = odata.createETagInformation(
Arrays.asList("\"ETag1\", ETag2", "w/\"ETag3\"", "W//\"ETag4\"", "W/ETag5",
"\"\"ETag6\"\"", " \"ETag7\"\"ETag7\" ", "\"ETag8\" \"ETag8\"",
"\"ETag 9\"", "\"ETag10\""));
assertFalse(etagInformation.isAll());
assertNotNull(etagInformation.getEtags());
assertThat(etagInformation.getEtags().size(), equalTo(2));
assertThat(etagInformation.getEtags(), hasItems("\"ETag1\"", "\"ETag10\""));
assertFalse(eTagInformation.isAll());
assertNotNull(eTagInformation.getETags());
assertThat(eTagInformation.getETags().size(), equalTo(2));
assertThat(eTagInformation.getETags(), hasItems("\"ETag1\"", "\"ETag10\""));
}
@Test
public void match() {
assertFalse(odata.createEtagInformation(Collections.<String> emptySet()).isMatchedBy("\"ETag\""));
assertFalse(odata.createEtagInformation(Collections.singleton("\"ETag\"")).isMatchedBy(null));
assertTrue(odata.createEtagInformation(Collections.singleton("\"ETag\"")).isMatchedBy("\"ETag\""));
assertTrue(odata.createEtagInformation(Collections.singleton("*")).isMatchedBy("\"ETag\""));
assertTrue(odata.createEtagInformation(Collections.singleton("\"ETag\"")).isMatchedBy("W/\"ETag\""));
assertTrue(odata.createEtagInformation(Collections.singleton("W/\"ETag\"")).isMatchedBy("\"ETag\""));
assertFalse(odata.createEtagInformation(Collections.singleton("\"ETag\"")).isMatchedBy("W/\"ETag2\""));
assertFalse(odata.createEtagInformation(Collections.singleton("W/\"ETag\"")).isMatchedBy("\"ETag2\""));
assertTrue(odata.createEtagInformation(Arrays.asList("\"ETag1\",\"ETag2\"", "\"ETag3\",\"ETag4\""))
assertFalse(odata.createETagInformation(Collections.<String> emptySet()).isMatchedBy("\"ETag\""));
assertFalse(odata.createETagInformation(Collections.singleton("\"ETag\"")).isMatchedBy(null));
assertTrue(odata.createETagInformation(Collections.singleton("\"ETag\"")).isMatchedBy("\"ETag\""));
assertTrue(odata.createETagInformation(Collections.singleton("*")).isMatchedBy("\"ETag\""));
assertTrue(odata.createETagInformation(Collections.singleton("\"ETag\"")).isMatchedBy("W/\"ETag\""));
assertTrue(odata.createETagInformation(Collections.singleton("W/\"ETag\"")).isMatchedBy("\"ETag\""));
assertFalse(odata.createETagInformation(Collections.singleton("\"ETag\"")).isMatchedBy("W/\"ETag2\""));
assertFalse(odata.createETagInformation(Collections.singleton("W/\"ETag\"")).isMatchedBy("\"ETag2\""));
assertTrue(odata.createETagInformation(Arrays.asList("\"ETag1\",\"ETag2\"", "\"ETag3\",\"ETag4\""))
.isMatchedBy("\"ETag4\""));
assertFalse(odata.createEtagInformation(Arrays.asList("\"ETag1\",\"ETag2\"", "\"ETag3\",\"ETag4\""))
assertFalse(odata.createETagInformation(Arrays.asList("\"ETag1\",\"ETag2\"", "\"ETag3\",\"ETag4\""))
.isMatchedBy("\"ETag5\""));
}
}

View File

@ -578,8 +578,8 @@ public class DataProvider {
}
}
}
private Entity getEntityByReference(final String entityId, final String rawServiceRoot)
protected Entity getEntityByReference(final String entityId, final String rawServiceRoot)
throws DataProviderException {
try {
final UriResourceEntitySet uriResource = odata.createUriHelper().parseEntityId(edm, entityId, rawServiceRoot);
@ -594,7 +594,7 @@ public class DataProvider {
throw new DataProviderException("Invalid entity-id", HttpStatusCode.BAD_REQUEST);
}
}
public static class DataProviderException extends ODataApplicationException {
private static final long serialVersionUID = 5098059649321796156L;
@ -603,7 +603,7 @@ public class DataProvider {
}
public DataProviderException(final String message) {
super(message, HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT);
this(message, HttpStatusCode.INTERNAL_SERVER_ERROR);
}
public DataProviderException(final String message, final HttpStatusCode statusCode) {

View File

@ -27,7 +27,6 @@ import org.apache.olingo.commons.api.data.EntityCollection;
import org.apache.olingo.commons.api.data.Link;
import org.apache.olingo.commons.api.data.Linked;
import org.apache.olingo.commons.api.data.Property;
import org.apache.olingo.commons.api.edm.Edm;
import org.apache.olingo.commons.api.edm.EdmBindingTarget;
import org.apache.olingo.commons.api.edm.EdmComplexType;
import org.apache.olingo.commons.api.edm.EdmEntityType;
@ -35,35 +34,23 @@ import org.apache.olingo.commons.api.edm.EdmNavigationProperty;
import org.apache.olingo.commons.api.edm.EdmProperty;
import org.apache.olingo.commons.api.edm.EdmStructuredType;
import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.server.api.deserializer.DeserializerException;
import org.apache.olingo.server.api.uri.UriHelper;
import org.apache.olingo.server.api.uri.UriResourceEntitySet;
import org.apache.olingo.server.tecsvc.data.DataProvider.DataProviderException;
public class RequestValidator {
private DataProvider provider;
private boolean isInsert;
private boolean isPatch;
private UriHelper uriHelper;
private Edm edm;
private String rawServiceRoot;
private final DataProvider provider;
private final boolean isInsert;
private final boolean isPatch;
private final String rawServiceRoot;
public RequestValidator(final DataProvider provider, final UriHelper uriHelper,
final Edm edm, final String rawServiceRoot) {
this.provider = provider;
isInsert = true;
this.uriHelper = uriHelper;
this.edm = edm;
this.rawServiceRoot = rawServiceRoot;
public RequestValidator(final DataProvider provider, final String rawServiceRoot) {
this(provider, false, false, rawServiceRoot);
}
public RequestValidator(final DataProvider provider, final boolean isUpdate, final boolean isPatch,
final UriHelper uriHelper, final Edm edm, final String rawServiceRoot) {
final String rawServiceRoot) {
this.provider = provider;
isInsert = !isUpdate;
this.isInsert = !isUpdate;
this.isPatch = isPatch;
this.uriHelper = uriHelper;
this.edm = edm;
this.rawServiceRoot = rawServiceRoot;
}
@ -89,15 +76,15 @@ public class RequestValidator {
newPath.add(edmProperty.getName());
final EdmBindingTarget target = edmBindingTarget.getRelatedBindingTarget(buildPath(newPath));
final ValidatioResult bindingResult = validateBinding(navigationBinding, edmProperty, target);
final ValidatioResult linkResult = validateNavigationLink(navigationLink,
final ValidationResult bindingResult = validateBinding(navigationBinding, edmProperty);
final ValidationResult linkResult = validateNavigationLink(navigationLink,
edmProperty,
target);
if ((isInsert && !edmProperty.isNullable()
&& (bindingResult != ValidatioResult.FOUND
&& linkResult != ValidatioResult.FOUND))
|| (!(isInsert && isPatch) && !edmProperty.isNullable() && linkResult == ValidatioResult.EMPTY)) {
&& (bindingResult != ValidationResult.FOUND
&& linkResult != ValidationResult.FOUND))
|| (!(isInsert && isPatch) && !edmProperty.isNullable() && linkResult == ValidationResult.EMPTY)) {
throw new DataProviderException("Navigation property " + navPropertyName + " must not be null",
HttpStatusCode.BAD_REQUEST);
}
@ -119,35 +106,35 @@ public class RequestValidator {
return builder.toString();
}
private ValidatioResult validateBinding(final Link navigationBindung, final EdmNavigationProperty edmProperty,
final EdmBindingTarget edmBindingTarget) throws DataProviderException {
if (navigationBindung == null) {
return ValidatioResult.NOT_FOUND;
private ValidationResult validateBinding(final Link navigationBinding, final EdmNavigationProperty edmProperty)
throws DataProviderException {
if (navigationBinding == null) {
return ValidationResult.NOT_FOUND;
}
if (edmProperty.isCollection()) {
if (navigationBindung.getBindingLinks().size() == 0) {
return ValidatioResult.EMPTY;
if (navigationBinding.getBindingLinks().size() == 0) {
return ValidationResult.EMPTY;
}
for (final String bindingLink : navigationBindung.getBindingLinks()) {
validateLink(bindingLink, edmBindingTarget);
for (final String bindingLink : navigationBinding.getBindingLinks()) {
validateLink(bindingLink);
}
} else {
if (navigationBindung.getBindingLink() == null) {
return ValidatioResult.EMPTY;
if (navigationBinding.getBindingLink() == null) {
return ValidationResult.EMPTY;
}
validateLink(navigationBindung.getBindingLink(), edmBindingTarget);
validateLink(navigationBinding.getBindingLink());
}
return ValidatioResult.FOUND;
return ValidationResult.FOUND;
}
private ValidatioResult validateNavigationLink(final Link navigationLink, final EdmNavigationProperty edmProperty,
private ValidationResult validateNavigationLink(final Link navigationLink, final EdmNavigationProperty edmProperty,
final EdmBindingTarget edmBindingTarget) throws DataProviderException {
if (navigationLink == null) {
return ValidatioResult.NOT_FOUND;
return ValidationResult.NOT_FOUND;
}
if (edmProperty.isCollection()) {
@ -168,21 +155,11 @@ public class RequestValidator {
}
}
return ValidatioResult.FOUND;
return ValidationResult.FOUND;
}
private void validateLink(final String bindingLink, final EdmBindingTarget edmBindungTarget)
throws DataProviderException {
try {
final UriResourceEntitySet uriInfo = uriHelper.parseEntityId(edm, bindingLink, rawServiceRoot);
final Entity entity = provider.read(uriInfo.getEntitySet(), uriInfo.getKeyPredicates());
if (entity == null) {
throw new DataProviderException("Entity not found", HttpStatusCode.NOT_FOUND);
}
} catch (DeserializerException e) {
throw new DataProviderException("Invalid binding link", HttpStatusCode.BAD_REQUEST);
}
private void validateLink(final String bindingLink) throws DataProviderException {
provider.getEntityByReference(bindingLink, rawServiceRoot);
}
private void validateEntitySetProperties(final List<Property> properties, final EdmBindingTarget edmBindingTarget,
@ -190,7 +167,7 @@ public class RequestValidator {
validateProperties(properties, edmBindingTarget, edmType, edmType.getKeyPredicateNames(), path);
}
private void validateProperties(final List<Property> properties, final EdmBindingTarget edmBingingTarget,
private void validateProperties(final List<Property> properties, final EdmBindingTarget edmBindingTarget,
final EdmStructuredType edmType, final List<String> keyPredicateNames, final List<String> path)
throws DataProviderException {
@ -212,7 +189,7 @@ public class RequestValidator {
}
// Validate property value
validatePropertyValue(property, edmProperty, edmBingingTarget, path);
validatePropertyValue(property, edmProperty, edmBindingTarget, path);
}
}
}
@ -259,7 +236,7 @@ public class RequestValidator {
return null;
}
private static enum ValidatioResult {
private static enum ValidationResult {
FOUND,
NOT_FOUND,
EMPTY

View File

@ -159,10 +159,8 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
final DeserializerResult deserializerResult =
odata.createDeserializer(ODataFormat.fromContentType(requestFormat))
.entity(request.getBody(), edmEntityType);
new RequestValidator(dataProvider,
odata.createUriHelper(),
serviceMetadata.getEdm(),
request.getRawBaseUri()).validate(edmEntitySet, deserializerResult.getEntity());
new RequestValidator(dataProvider, request.getRawBaseUri())
.validate(edmEntitySet, deserializerResult.getEntity());
entity = dataProvider.create(edmEntitySet);
dataProvider.update(request.getRawBaseUri(), edmEntitySet, entity, deserializerResult.getEntity(), false,
@ -213,8 +211,6 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
new RequestValidator(dataProvider,
true, // Update
request.getMethod() == HttpMethod.PATCH,
odata.createUriHelper(),
serviceMetadata.getEdm(),
request.getRawBaseUri()).validate(edmEntitySet, changedEntity);
dataProvider.update(request.getRawBaseUri(), edmEntitySet, entity, changedEntity,

View File

@ -32,7 +32,7 @@ import org.apache.olingo.commons.api.edm.EdmFunction;
import org.apache.olingo.commons.api.edm.EdmNavigationProperty;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.server.api.EtagInformation;
import org.apache.olingo.server.api.ETagInformation;
import org.apache.olingo.server.api.OData;
import org.apache.olingo.server.api.ODataApplicationException;
import org.apache.olingo.server.api.ServiceMetadata;
@ -262,12 +262,12 @@ public abstract class TechnicalProcessor implements Processor {
final Collection<String> ifMatchHeaders, final Collection<String> ifNoneMatchHeaders)
throws ODataApplicationException {
if (eTag != null) {
final EtagInformation ifMatch = odata.createEtagInformation(ifMatchHeaders);
if (!ifMatch.isMatchedBy(eTag) && !ifMatch.getEtags().isEmpty()) {
final ETagInformation ifMatch = odata.createETagInformation(ifMatchHeaders);
if (!ifMatch.isMatchedBy(eTag) && !ifMatch.getETags().isEmpty()) {
throw new ODataApplicationException("The If-Match precondition is not fulfilled.",
HttpStatusCode.PRECONDITION_FAILED.getStatusCode(), Locale.ROOT);
}
if (odata.createEtagInformation(ifNoneMatchHeaders).isMatchedBy(eTag)) {
if (odata.createETagInformation(ifNoneMatchHeaders).isMatchedBy(eTag)) {
throw new ODataApplicationException("The entity has not been modified.",
HttpStatusCode.NOT_MODIFIED.getStatusCode(), Locale.ROOT);
}
@ -278,9 +278,9 @@ public abstract class TechnicalProcessor implements Processor {
final Collection<String> ifMatchHeaders, final Collection<String> ifNoneMatchHeaders)
throws ODataApplicationException {
if (eTag != null) {
final EtagInformation ifMatch = odata.createEtagInformation(ifMatchHeaders);
final EtagInformation ifNoneMatch = odata.createEtagInformation(ifNoneMatchHeaders);
if (!ifMatch.isMatchedBy(eTag) && !ifMatch.getEtags().isEmpty()
final ETagInformation ifMatch = odata.createETagInformation(ifMatchHeaders);
final ETagInformation ifNoneMatch = odata.createETagInformation(ifNoneMatchHeaders);
if (!ifMatch.isMatchedBy(eTag) && !ifMatch.getETags().isEmpty()
|| ifNoneMatch.isMatchedBy(eTag)) {
throw new ODataApplicationException("The preconditions are not fulfilled.",
HttpStatusCode.PRECONDITION_FAILED.getStatusCode(), Locale.ROOT);

View File

@ -27,7 +27,6 @@ import org.apache.olingo.commons.api.edm.EdmProperty;
import org.apache.olingo.commons.api.edm.EdmType;
import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.server.api.ODataApplicationException;
import org.apache.olingo.server.tecsvc.processor.queryoptions.expression.primitive.EdmNull;
public class TypedOperand extends VisitorOperand {
@ -56,7 +55,7 @@ public class TypedOperand extends VisitorOperand {
@Override
public TypedOperand asTypedOperand(final EdmPrimitiveType... asTypes) throws ODataApplicationException {
if (type.equals(EdmNull.getInstance())) {
if (is(primNull)) {
return this;
} else if (isNull()) {
return new TypedOperand(null, asTypes[0]);
@ -103,7 +102,7 @@ public class TypedOperand extends VisitorOperand {
if (type == oType && value != null && other.getValue() != null
&& value.getClass() == other.getValue().getClass()) {
return this;
} else if (isNullLiteral() || other.isNullLiteral()) {
} else if (is(primNull) || other.is(primNull)) {
return this;
}
@ -132,16 +131,12 @@ public class TypedOperand extends VisitorOperand {
return clazz.cast(value);
}
public boolean isNullLiteral() {
return type.equals(EdmNull.getInstance());
}
public boolean isNull() {
return isNullLiteral() || value == null;
return is(primNull) || value == null;
}
public boolean isIntegerType() {
return is(
return is(primNull,
primByte,
primSByte,
primInt16,
@ -150,23 +145,18 @@ public class TypedOperand extends VisitorOperand {
}
public boolean isDecimalType() {
return is(
return is(primNull,
primSingle,
primDouble,
primDecimal);
}
public boolean is(final EdmPrimitiveType... types) {
if (isNullLiteral()) {
return true;
}
for (EdmPrimitiveType type : types) {
if (type.equals(this.type)) {
return true;
}
}
return false;
}

View File

@ -24,7 +24,6 @@ import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
import org.apache.olingo.commons.api.edm.EdmProperty;
import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.server.api.ODataApplicationException;
import org.apache.olingo.server.tecsvc.processor.queryoptions.expression.primitive.EdmNull;
public class UntypedOperand extends VisitorOperand {
@ -43,8 +42,8 @@ public class UntypedOperand extends VisitorOperand {
Object newValue = null;
// First try the null literal
if ((newValue = tryCast(literal, EdmNull.getInstance())) != null) {
return new TypedOperand(newValue, EdmNull.getInstance());
if ((newValue = tryCast(literal, primNull)) != null) {
return new TypedOperand(newValue, primNull);
}
// Than try the given types
@ -65,8 +64,8 @@ public class UntypedOperand extends VisitorOperand {
Object newValue = null;
// Null literal
if ((newValue = tryCast(literal, EdmNull.getInstance())) != null) {
return new TypedOperand(newValue, EdmNull.getInstance());
if (primNull.validate(literal, null, null, null, null, null)) {
return new TypedOperand(newValue, primNull);
}
// String

View File

@ -29,11 +29,13 @@ import org.apache.olingo.commons.api.edm.EdmProperty;
import org.apache.olingo.commons.api.edm.EdmType;
import org.apache.olingo.server.api.OData;
import org.apache.olingo.server.api.ODataApplicationException;
import org.apache.olingo.server.tecsvc.processor.queryoptions.expression.primitive.EdmNull;
public abstract class VisitorOperand {
final static private HashMap<EdmType, Class<?>> defaultTypeMapping = new HashMap<EdmType, Class<?>>();
protected Object value;
protected static final OData oData;
protected static final EdmPrimitiveType primNull = EdmNull.getInstance();
protected static final EdmPrimitiveType primString;
protected static final EdmPrimitiveType primBoolean;
protected static final EdmPrimitiveType primDateTimeOffset;

View File

@ -37,6 +37,7 @@ import org.apache.olingo.server.api.OData;
import org.apache.olingo.server.api.ODataApplicationException;
import org.apache.olingo.server.tecsvc.processor.queryoptions.expression.operand.TypedOperand;
import org.apache.olingo.server.tecsvc.processor.queryoptions.expression.operand.VisitorOperand;
import org.apache.olingo.server.tecsvc.processor.queryoptions.expression.primitive.EdmNull;
public class MethodCallOperator {
@ -317,8 +318,10 @@ public class MethodCallOperator {
throws ODataApplicationException {
final TypedOperand operand = parameters.get(0).asTypedOperand();
if (operand.is(expectedTypes)) {
if (!operand.isNull()) {
if (operand.isNull()) {
return new TypedOperand(null, EdmNull.getInstance());
} else {
if (operand.is(expectedTypes)) {
Calendar calendar = null;
if (operand.is(primDate)) {
calendar = operand.getTypedValue(Calendar.class);
@ -331,13 +334,10 @@ public class MethodCallOperator {
} else {
throw new ODataApplicationException("Invalid type", HttpStatusCode.BAD_REQUEST.getStatusCode(), Locale.ROOT);
}
return new TypedOperand(f.perform(calendar, operand), returnType);
} else {
return new TypedOperand(null, returnType);
}
} else {
throw new ODataApplicationException("Invalid type", HttpStatusCode.BAD_REQUEST.getStatusCode(), Locale.ROOT);
}
}
}
@ -345,7 +345,7 @@ public class MethodCallOperator {
throws ODataApplicationException {
List<String> stringParameters = getParametersAsString();
if (stringParameters.contains(null)) {
return new TypedOperand(null, returnValue);
return new TypedOperand(null, EdmNull.getInstance());
} else {
return new TypedOperand(f.perform(stringParameters), returnValue);
}

View File

@ -31,15 +31,26 @@ public final class EdmNull implements EdmPrimitiveType {
return instance;
}
@Override
public String getNamespace() {
return EDM_NAMESPACE;
}
@Override
public String getName() {
return getClass().getSimpleName().substring(3);
}
@Override
public EdmTypeKind getKind() {
return EdmTypeKind.PRIMITIVE;
}
@Override
public Class<?> getDefaultType() {
return Object.class;
}
protected String uriPrefix = "";
protected String uriSuffix = "";
@Override
public FullQualifiedName getFullQualifiedName() {
return new FullQualifiedName(getNamespace(), getName());
@ -54,13 +65,8 @@ public final class EdmNull implements EdmPrimitiveType {
public boolean validate(final String value,
final Boolean isNullable, final Integer maxLength, final Integer precision, final Integer scale,
final Boolean isUnicode) {
try {
valueOfString(value, isNullable, maxLength, precision, scale, isUnicode, getDefaultType());
return true;
} catch (final EdmPrimitiveTypeException e) {
return false;
}
return value == null && (isNullable == null || isNullable)
|| value.equals("null");
}
@Override
@ -68,14 +74,17 @@ public final class EdmNull implements EdmPrimitiveType {
final Boolean isNullable, final Integer maxLength, final Integer precision,
final Integer scale, final Boolean isUnicode, final Class<T> returnType)
throws EdmPrimitiveTypeException {
if (value == null) {
if (isNullable != null && !isNullable) {
throw new EdmPrimitiveTypeException("The literal 'null' is not allowed.");
}
return null;
}
return internalValueOfString(value, isNullable, maxLength, precision, scale, isUnicode, returnType);
if (value.equals("null")) {
return null;
} else {
throw new EdmPrimitiveTypeException("The literal '" + value + "' has illegal content.");
}
}
@Override
@ -88,28 +97,17 @@ public final class EdmNull implements EdmPrimitiveType {
}
return null;
}
return internalValueToString(value, isNullable, maxLength, precision, scale, isUnicode);
return "null";
}
@Override
public String toUriLiteral(final String literal) {
return literal == null ? null :
uriPrefix.isEmpty() && uriSuffix.isEmpty() ? literal : uriPrefix + literal + uriSuffix;
return literal == null ? null : literal;
}
@Override
public String fromUriLiteral(final String literal) throws EdmPrimitiveTypeException {
if (literal == null) {
return null;
} else if (uriPrefix.isEmpty() && uriSuffix.isEmpty()) {
return literal;
} else if (literal.length() >= uriPrefix.length() + uriSuffix.length()
&& literal.startsWith(uriPrefix) && literal.endsWith(uriSuffix)) {
return literal.substring(uriPrefix.length(), literal.length() - uriSuffix.length());
} else {
throw new EdmPrimitiveTypeException("The literal '" + literal + "' has illegal content.");
}
return literal == null ? null : literal;
}
@Override
@ -117,26 +115,6 @@ public final class EdmNull implements EdmPrimitiveType {
return new FullQualifiedName(getNamespace(), getName()).getFullQualifiedNameAsString();
}
protected <T> T internalValueOfString(final String value, final Boolean isNullable, final Integer maxLength,
final Integer precision,
final Integer scale, final Boolean isUnicode, final Class<T> returnType) throws EdmPrimitiveTypeException {
if (!value.equals("null")) {
throw new EdmPrimitiveTypeException("The literal '" + value + "' has illegal content.");
}
if (returnType.isAssignableFrom(Object.class)) {
return returnType.cast(new Object());
} else {
throw new ClassCastException("unsupported return type " + returnType.getSimpleName());
}
}
protected <T> String internalValueToString(final T value, final Boolean isNullable, final Integer maxLength,
final Integer precision,
final Integer scale, final Boolean isUnicode) throws EdmPrimitiveTypeException {
return "null";
}
@Override
public boolean equals(final Object obj) {
return this == obj || obj != null && getClass() == obj.getClass();
@ -146,20 +124,4 @@ public final class EdmNull implements EdmPrimitiveType {
public int hashCode() {
return getClass().hashCode();
}
@Override
public String getNamespace() {
return EDM_NAMESPACE;
}
@Override
public String getName() {
return getClass().getSimpleName().substring(3);
}
@Override
public EdmTypeKind getKind() {
return EdmTypeKind.PRIMITIVE;
}
}