From 4aa8a676ef59fd372ffdccd0cc6c5f1448cc354d Mon Sep 17 00:00:00 2001 From: Michael Bolz Date: Mon, 4 May 2015 15:07:47 +0200 Subject: [PATCH 1/2] [OLINGO-648] Added ODataClientFactory in API module --- .../olingo/client/api/ODataClientFactory.java | 109 ++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 lib/client-api/src/main/java/org/apache/olingo/client/api/ODataClientFactory.java diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/ODataClientFactory.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/ODataClientFactory.java new file mode 100644 index 000000000..8c0d3d2c9 --- /dev/null +++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/ODataClientFactory.java @@ -0,0 +1,109 @@ +/* + * 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 org.apache.olingo.commons.api.edm.Edm; +import org.apache.olingo.commons.api.format.ODataFormat; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; + +/** + * Helper to access an implementation for the API client library. + */ +public final class ODataClientFactory { + + private static final String ODATA_CLIENT_IMPL_CLASS = "org.apache.olingo.client.core.ODataClientImpl"; + private static final String ODATA_EDM_CLIENT_IMPL_CLASS = "org.apache.olingo.client.core.EdmEnabledODataClientImpl"; + public static final String ODATA_CLIENT_IMPL_SYS_PROPERTY = "ORG_APACHE_OLINGO_CLIENT_IMPL_FQN"; + public static final String ODATA_EMD_CLIENT_IMPL_SYS_PROPERTY = "ORG_APACHE_OLINGO_EDM_CLIENT_IMPL_FQN"; + + /** + * Create an new ODataClient based on via system property ODATA_CLIENT_IMPL_SYS_PROPERTY + * class name or if not net the default ODATA_CLIENT_IMPL_CLASS set class. + * @return create ODataClient + */ + public static ODataClient getClient() { + String clientImplClassName = System.getProperty(ODATA_CLIENT_IMPL_SYS_PROPERTY); + if(clientImplClassName == null) { + clientImplClassName = ODATA_CLIENT_IMPL_CLASS; + } + return loadClass(ODataClient.class, clientImplClassName); + } + + /** + * Create an new EdmEnabledODataClient based on via system property ODATA_EMD_CLIENT_IMPL_SYS_PROPERTY + * class name or if not net the default ODATA_EDM_CLIENT_IMPL_CLASS set class. + * @param serviceRoot used service root + * @return create ODataClient + */ + public static EdmEnabledODataClient getEdmEnabledClient(final String serviceRoot) { + return getEdmEnabledClient(serviceRoot, null, null); + } + + /** + * Create an new EdmEnabledODataClient based on via system property ODATA_EMD_CLIENT_IMPL_SYS_PROPERTY + * class name or if not net the default ODATA_EDM_CLIENT_IMPL_CLASS set class. + * @param serviceRoot used service root + * @param edm used Edm + * @param metadataETag used metadataETag + * @return create ODataClient + */ + public static EdmEnabledODataClient getEdmEnabledClient( + final String serviceRoot, final Edm edm, final String metadataETag) { + + String clientImplClassName = System.getProperty(ODATA_EMD_CLIENT_IMPL_SYS_PROPERTY); + if(clientImplClassName == null) { + clientImplClassName = ODATA_EDM_CLIENT_IMPL_CLASS; + } + final EdmEnabledODataClient instance = + loadClass(EdmEnabledODataClient.class, clientImplClassName, + new Class[] { String.class, Edm.class, String.class }, + new Object[] { serviceRoot, edm, metadataETag }); + instance.getConfiguration().setDefaultPubFormat(ODataFormat.JSON); + return instance; + } + + private static T loadClass(Class typeOfClass, String className) { + return loadClass(typeOfClass, className, null, null); + } + + private static T loadClass(Class typeOfClass, String className, + Class[] ctorParameterClasses, + Object[] ctorParameters) { + try { + Class clazz = Thread.currentThread().getContextClassLoader().loadClass(className); + if (ctorParameters == null || ctorParameterClasses == null) { + return typeOfClass.cast(clazz.newInstance()); + } + Constructor ctor = clazz.getConstructor(ctorParameterClasses); + return typeOfClass.cast(ctor.newInstance(ctorParameters)); + } catch (ClassNotFoundException e) { + throw new RuntimeException("Requested class '" + className + "' could not be loaded.", e); + } catch (InstantiationException e) { + throw new RuntimeException("Requested class '" + className + "' could not be loaded.", e); + } catch (IllegalAccessException e) { + throw new RuntimeException("Requested class '" + className + "' could not be loaded.", e); + } catch (NoSuchMethodException e) { + throw new RuntimeException("Requested class '" + className + "' could not be loaded.", e); + } catch (InvocationTargetException e) { + throw new RuntimeException("Requested class '" + className + "' could not be loaded.", e); + } + } +} From e0e6c859a1c5defc3985644686d28280231afe3a Mon Sep 17 00:00:00 2001 From: Michael Bolz Date: Tue, 5 May 2015 14:21:47 +0200 Subject: [PATCH 2/2] [OLINGO-648] Renamed to Builder for sepration from Factory in core --- ...ntFactory.java => ODataClientBuilder.java} | 88 ++++++++++++++--- .../client/core/ODataClientBuilderTest.java | 94 +++++++++++++++++++ 2 files changed, 171 insertions(+), 11 deletions(-) rename lib/client-api/src/main/java/org/apache/olingo/client/api/{ODataClientFactory.java => ODataClientBuilder.java} (60%) create mode 100644 lib/client-core/src/test/java/org/apache/olingo/client/core/ODataClientBuilderTest.java diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/ODataClientFactory.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/ODataClientBuilder.java similarity index 60% rename from lib/client-api/src/main/java/org/apache/olingo/client/api/ODataClientFactory.java rename to lib/client-api/src/main/java/org/apache/olingo/client/api/ODataClientBuilder.java index 8c0d3d2c9..bd3cbdeae 100644 --- a/lib/client-api/src/main/java/org/apache/olingo/client/api/ODataClientFactory.java +++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/ODataClientBuilder.java @@ -25,21 +25,86 @@ import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; /** - * Helper to access an implementation for the API client library. + *

+ * Builder to create an ODataClient for the API client library. + * This builder is dependent that an according implementation for the ODataClient and or + * EdmEnabledODataClient is available in class path. + *

+ *

+ * This Builder should only be used in use cases were a direct access to the client-core + * library is not possible. + * If direct access is possible it is highly recommended to use the + * ODataClientFactory provided in the client-core library. + *

+ *

+ * By default the ODataClientBuilder use the default Olingo V4 client core implementations + * (org.apache.olingo.client.core.ODataClientImpl and + * org.apache.olingo.client.core.EdmEnabledODataClientImpl) which can be + * overwritten via the System properties ODATA_CLIENT_IMPL_SYS_PROPERTY + * and ODATA_EMD_CLIENT_IMPL_SYS_PROPERTY. + *

*/ -public final class ODataClientFactory { +public final class ODataClientBuilder { private static final String ODATA_CLIENT_IMPL_CLASS = "org.apache.olingo.client.core.ODataClientImpl"; private static final String ODATA_EDM_CLIENT_IMPL_CLASS = "org.apache.olingo.client.core.EdmEnabledODataClientImpl"; public static final String ODATA_CLIENT_IMPL_SYS_PROPERTY = "ORG_APACHE_OLINGO_CLIENT_IMPL_FQN"; public static final String ODATA_EMD_CLIENT_IMPL_SYS_PROPERTY = "ORG_APACHE_OLINGO_EDM_CLIENT_IMPL_FQN"; + /** + * Builder class + */ + public static class ClientBuilder { + private final String serviceRoot; + private Edm edm; + private String metadataETag; + + /** + * Create the builder for an EdmEnabledODataClient. + * + * @param serviceRoot service root to use + */ + public ClientBuilder(String serviceRoot) { + this.serviceRoot = serviceRoot; + } + + /** + * Set the edm to use for edm enabled client + * @param edm edm to use for edm enabled client + * @return current client builder + */ + public ClientBuilder edm(final Edm edm) { + this.edm = edm; + return this; + } + + /** + * Set the metadataETag to use for edm enabled client + * @param metadataETag edm to use for edm enabled client + * @return current client builder + */ + public ClientBuilder metadataETag(final String metadataETag) { + this.metadataETag = metadataETag; + return this; + } + + /** + * Create an new EdmEnabledODataClient based on via system property ODATA_EMD_CLIENT_IMPL_SYS_PROPERTY + * class name or if not net the default ODATA_EDM_CLIENT_IMPL_CLASS set class + * with before set serviceRoot and optional edm and optinal metadataETag. + * @return new created ODataClient + */ + public EdmEnabledODataClient createClient() { + return ODataClientBuilder.createEdmEnabledClient(serviceRoot, edm, metadataETag); + } + } + /** * Create an new ODataClient based on via system property ODATA_CLIENT_IMPL_SYS_PROPERTY * class name or if not net the default ODATA_CLIENT_IMPL_CLASS set class. * @return create ODataClient */ - public static ODataClient getClient() { + public static ODataClient createClient() { String clientImplClassName = System.getProperty(ODATA_CLIENT_IMPL_SYS_PROPERTY); if(clientImplClassName == null) { clientImplClassName = ODATA_CLIENT_IMPL_CLASS; @@ -48,15 +113,16 @@ public final class ODataClientFactory { } /** - * Create an new EdmEnabledODataClient based on via system property ODATA_EMD_CLIENT_IMPL_SYS_PROPERTY - * class name or if not net the default ODATA_EDM_CLIENT_IMPL_CLASS set class. - * @param serviceRoot used service root - * @return create ODataClient + * Initiate the builder for an EdmEnabledODataClient. + * + * @param serviceRoot service root to use + * @return initiated client builder */ - public static EdmEnabledODataClient getEdmEnabledClient(final String serviceRoot) { - return getEdmEnabledClient(serviceRoot, null, null); + public static ClientBuilder with(String serviceRoot) { + return new ClientBuilder(serviceRoot); } + /** * Create an new EdmEnabledODataClient based on via system property ODATA_EMD_CLIENT_IMPL_SYS_PROPERTY * class name or if not net the default ODATA_EDM_CLIENT_IMPL_CLASS set class. @@ -65,8 +131,8 @@ public final class ODataClientFactory { * @param metadataETag used metadataETag * @return create ODataClient */ - public static EdmEnabledODataClient getEdmEnabledClient( - final String serviceRoot, final Edm edm, final String metadataETag) { + private static EdmEnabledODataClient createEdmEnabledClient( + final String serviceRoot, final Edm edm, final String metadataETag) { String clientImplClassName = System.getProperty(ODATA_EMD_CLIENT_IMPL_SYS_PROPERTY); if(clientImplClassName == null) { diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/ODataClientBuilderTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/ODataClientBuilderTest.java new file mode 100644 index 000000000..0bfb76e28 --- /dev/null +++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/ODataClientBuilderTest.java @@ -0,0 +1,94 @@ +/* + * 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.core; + +import org.apache.olingo.client.api.EdmEnabledODataClient; +import org.apache.olingo.client.api.ODataClient; +import org.apache.olingo.client.api.ODataClientBuilder; +import org.apache.olingo.commons.api.edm.Edm; +import org.junit.Test; +import org.mockito.Mockito; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +public class ODataClientBuilderTest { + + @Test + public void testDefault() { + ODataClient client = ODataClientBuilder.createClient(); + assertNotNull(client); + assertTrue(client instanceof ODataClientImpl); + assertFalse(client instanceof EdmEnabledODataClientImpl); + + EdmEnabledODataClient edmClient = ODataClientBuilder.with("http://serviceRoot").createClient(); + assertNotNull(client); + assertTrue(edmClient instanceof ODataClientImpl); + assertTrue(edmClient instanceof EdmEnabledODataClientImpl); + } + + @Test + public void testSystemProperty() { + //CHECKSTYLE:OFF + System.setProperty(ODataClientBuilder.ODATA_CLIENT_IMPL_SYS_PROPERTY, MyODataClient.class.getName()); + ODataClient client = ODataClientBuilder.createClient(); + assertNotNull(client); + assertTrue(client instanceof ODataClientImpl); + assertFalse(client instanceof EdmEnabledODataClientImpl); + assertTrue(client instanceof MyODataClient); + + System.setProperty(ODataClientBuilder.ODATA_EMD_CLIENT_IMPL_SYS_PROPERTY, MyEdmODataClient.class.getName()); + EdmEnabledODataClient edmClient = ODataClientBuilder.with("http://serviceRoot").createClient(); + assertNotNull(client); + assertTrue(edmClient instanceof ODataClientImpl); + assertTrue(edmClient instanceof EdmEnabledODataClientImpl); + assertTrue(edmClient instanceof MyEdmODataClient); + assertNull(edmClient.getCachedEdm()); + + Edm edm = Mockito.mock(Edm.class); + edmClient = ODataClientBuilder.with("http://serviceRoot").edm(edm).metadataETag("ETAG").createClient(); + assertNotNull(client); + assertTrue(edmClient instanceof ODataClientImpl); + assertTrue(edmClient instanceof EdmEnabledODataClientImpl); + assertTrue(edmClient instanceof MyEdmODataClient); + assertNotNull(edmClient.getCachedEdm()); + + System.clearProperty(ODataClientBuilder.ODATA_CLIENT_IMPL_SYS_PROPERTY); + System.clearProperty(ODataClientBuilder.ODATA_EMD_CLIENT_IMPL_SYS_PROPERTY); + //CHECKSTYLE:ON + } + + public static class MyODataClient extends ODataClientImpl { + } + + public static class MyEdmODataClient extends EdmEnabledODataClientImpl { + private Edm myEdm; + public MyEdmODataClient(String serviceRoot, Edm edm, String metadataETag) { + super(serviceRoot, edm, metadataETag); + this.myEdm = edm; + } + + @Override + public Edm getCachedEdm() { + return myEdm; + } + } +}