package org.odata4j.examples.producer.inmemory; import static org.odata4j.examples.JaxRsImplementation.JERSEY; import java.net.URL; import java.util.ArrayList; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Map.Entry; import org.core4j.Enumerable; import org.core4j.Enumerables; import org.core4j.Func; import org.core4j.Func1; import org.core4j.Funcs; import org.core4j.ThrowingFunc; import org.odata4j.core.NamespacedAnnotation; import org.odata4j.core.OCollection; import org.odata4j.core.OCollections; import org.odata4j.core.OComplexObject; import org.odata4j.core.OComplexObjects; import org.odata4j.core.OProperties; import org.odata4j.core.OProperty; import org.odata4j.core.OSimpleObjects; import org.odata4j.core.PrefixedNamespace; import org.odata4j.edm.EdmAnnotation; import org.odata4j.edm.EdmAnnotationAttribute; import org.odata4j.edm.EdmComplexType; import org.odata4j.edm.EdmDecorator; import org.odata4j.edm.EdmDocumentation; import org.odata4j.edm.EdmEntitySet; import org.odata4j.edm.EdmEntityType; import org.odata4j.edm.EdmItem; import org.odata4j.edm.EdmProperty; import org.odata4j.edm.EdmSimpleType; import org.odata4j.edm.EdmStructuralType; import org.odata4j.examples.AbstractExample; import org.odata4j.examples.ODataServerFactory; import org.odata4j.producer.PropertyPath; import org.odata4j.producer.inmemory.InMemoryProducer; import org.odata4j.producer.resources.DefaultODataProducerProvider; public class InMemoryProducerExample extends AbstractExample { public static void main(String[] args) { InMemoryProducerExample example = new InMemoryProducerExample(); example.run(args); } @SuppressWarnings({ "unchecked", "rawtypes" }) private void run(String[] args) { String endpointUri = "http://localhost:8887/InMemoryProducerExample.svc/"; // InMemoryProducer is a readonly odata provider that serves up POJOs as entities using bean properties // call InMemoryProducer.register to declare a new entity-set, providing a entity source function and a propertyname to serve as the key final InMemoryProducer producer = new InMemoryProducer("InMemoryProducerExample", null, 100, new MyEdmDecorator(), null); // expose this jvm's thread information (Thread instances) as an entity-set called "Threads" producer.register(Thread.class, "Threads", new Func<Iterable<Thread>>() { public Iterable<Thread> apply() { ThreadGroup tg = Thread.currentThread().getThreadGroup(); while (tg.getParent() != null) tg = tg.getParent(); Thread[] threads = new Thread[1000]; int count = tg.enumerate(threads, true); return Enumerable.create(threads).take(count); } }, "Id"); // expose current system properties (Map.Entry instances) as an entity-set called "SystemProperties" producer.register(Entry.class, "SystemProperties", new Func<Iterable<Entry>>() { public Iterable<Entry> apply() { return (Iterable<Entry>) (Object) System.getProperties().entrySet(); } }, "Key"); // expose current environment variables (Map.Entry instances) as an entity-set called "EnvironmentVariables" producer.register(Entry.class, "EnvironmentVariables", new Func<Iterable<Entry>>() { public Iterable<Entry> apply() { return (Iterable<Entry>) (Object) System.getenv().entrySet(); } }, "Key"); // expose this producer's entity-types (EdmEntityType instances) as an entity-set called "EdmEntityTypes" producer.register(EdmEntityType.class, "EdmEntityTypes", new Func<Iterable<EdmEntityType>>() { public Iterable<EdmEntityType> apply() { return producer.getMetadata().getEntityTypes(); } }, "FullyQualifiedTypeName"); // expose a current listing of exchange traded funds sourced from an external csv (EtfInfo instances) as an entity-set called "ETFs" producer.register(EtfInfo.class, "ETFs", Funcs.wrap(new ThrowingFunc<Iterable<EtfInfo>>() { public Iterable<EtfInfo> apply() throws Exception { return getETFs(); } }), "Symbol"); // expose an large list of integers as an entity-set called "Integers" producer.register(Integer.class, Integer.class, "Integers", new Func<Iterable<Integer>>() { public Iterable<Integer> apply() { return Enumerable.range(0, Integer.MAX_VALUE); } }, Funcs.method(Integer.class, Integer.class, "intValue")); // register the producer as the static instance, then launch the http server DefaultODataProducerProvider.setInstance(producer); new ODataServerFactory(JERSEY).hostODataServer(endpointUri); } private static Iterable<EtfInfo> getETFs() throws Exception { return Enumerables.lines(new URL("http://www.masterdata.com/HelpFiles/ETF_List_Downloads/AllETFs.csv")).select(new Func1<String, EtfInfo>() { public EtfInfo apply(String csvLine) { return EtfInfo.parse(csvLine); } }).skip(1); // skip header line } public static class EtfInfo { private final String name; private final String symbol; private final String fundType; private EtfInfo(String name, String symbol, String fundType) { this.name = name; this.symbol = symbol; this.fundType = fundType; } public static EtfInfo parse(String csvLine) { csvLine = csvLine.substring(0, csvLine.lastIndexOf(',')); int i = csvLine.lastIndexOf(','); String type = csvLine.substring(i + 1); csvLine = csvLine.substring(0, csvLine.lastIndexOf(',')); i = csvLine.lastIndexOf(','); String sym = csvLine.substring(i + 1); csvLine = csvLine.substring(0, csvLine.lastIndexOf(',')); String name = csvLine; name = name.startsWith("\"") ? name.substring(1) : name; name = name.endsWith("\"") ? name.substring(0, name.length() - 1) : name; name = name.replace("\u00A0", " "); return new EtfInfo(name, sym, type); } public String getName() { return name; } public String getSymbol() { return symbol; } public String getFundType() { return fundType; } } public static class MyEdmDecorator implements EdmDecorator { public static final String namespace = "http://tempuri.org"; public static final String prefix = "inmem"; private final List<PrefixedNamespace> namespaces = new ArrayList<PrefixedNamespace>(1); private final EdmComplexType schemaInfoType; public MyEdmDecorator() { namespaces.add(new PrefixedNamespace(namespace, prefix)); this.schemaInfoType = createSchemaInfoType().build(); } @Override public List<PrefixedNamespace> getNamespaces() { return namespaces; } @Override public EdmDocumentation getDocumentationForSchema(String namespace) { return new EdmDocumentation("InMemoryProducerExample", "This schema exposes a few example types to demonstrate the InMemoryProducer"); } private EdmComplexType.Builder createSchemaInfoType() { List<EdmProperty.Builder> props = new ArrayList<EdmProperty.Builder>(); EdmProperty.Builder ep = EdmProperty.newBuilder("Author").setType(EdmSimpleType.STRING); props.add(ep); ep = EdmProperty.newBuilder("SeeAlso").setType(EdmSimpleType.STRING); props.add(ep); return EdmComplexType.newBuilder().setNamespace(namespace).setName("SchemaInfo").addProperties(props); } @Override public List<EdmAnnotation<?>> getAnnotationsForSchema(String namespace) { List<EdmAnnotation<?>> annots = new ArrayList<EdmAnnotation<?>>(); annots.add(new EdmAnnotationAttribute(namespace, prefix, "Version", "1.0 early experience pre-alpha")); List<OProperty<?>> p = new ArrayList<OProperty<?>>(); p.add(OProperties.string("Author", "Xavier S. Dumont")); p.add(OProperties.string("SeeAlso", "InMemoryProducerExample.java")); annots.add(EdmAnnotation.element(namespace, prefix, "SchemaInfo", OComplexObject.class, OComplexObjects.create(schemaInfoType, p))); annots.add(EdmAnnotation.element(namespace, prefix, "Tags", OCollection.class, OCollections.newBuilder(EdmSimpleType.STRING) .add(OSimpleObjects.create(EdmSimpleType.STRING, "tag1")) .add(OSimpleObjects.create(EdmSimpleType.STRING, "tag2")) .build())); return annots; } @Override public EdmDocumentation getDocumentationForEntityType(String namespace, String typeName) { return null; } @Override public List<EdmAnnotation<?>> getAnnotationsForEntityType(String namespace, String typeName) { return null; } @Override public Object resolveStructuralTypeProperty(EdmStructuralType st, PropertyPath path) throws IllegalArgumentException { return null; } @Override public EdmDocumentation getDocumentationForProperty(String namespace, String typename, String propName) { return null; } @Override public List<EdmAnnotation<?>> getAnnotationsForProperty(String namespace, String typename, String propName) { return null; } @Override public Object resolvePropertyProperty(EdmProperty st, PropertyPath path) throws IllegalArgumentException { return null; } @Override public Object getAnnotationValueOverride(EdmItem item, NamespacedAnnotation<?> annot, boolean flatten, Locale locale, Map<String, String> options) { return null; } @Override public void decorateEntity(EdmEntitySet entitySet, EdmItem item, EdmItem originalQueryItem, List<OProperty<?>> props, boolean flatten, Locale locale, Map<String, String> options) { // no-op } } }