001package org.nasdanika.html.model.html.gen; 002 003import java.io.InputStream; 004import java.util.Map; 005 006import org.eclipse.emf.common.notify.impl.AdapterImpl; 007import org.eclipse.emf.ecore.EObject; 008import org.json.JSONArray; 009import org.json.JSONObject; 010import org.nasdanika.common.Context; 011import org.nasdanika.common.Function; 012import org.nasdanika.common.ListCompoundSupplierFactory; 013import org.nasdanika.common.MapCompoundSupplierFactory; 014import org.nasdanika.common.Supplier; 015import org.nasdanika.common.SupplierFactory; 016import org.nasdanika.common.Util; 017import org.nasdanika.emf.EObjectAdaptable; 018import org.nasdanika.html.Tag; 019import org.nasdanika.ncore.EObjectProperty; 020import org.nasdanika.ncore.Property; 021 022public class ListSupplierFactoryAdapter extends AdapterImpl implements SupplierFactory<InputStream> { 023 024 protected ListSupplierFactoryAdapter(org.nasdanika.ncore.List list) { 025 setTarget(list); 026 } 027 028 @Override 029 public Supplier<InputStream> create(Context ctx) { 030 SupplierFactory<JSONArray> jsf = createJsonArraySupplierFactory((org.nasdanika.ncore.List) getTarget()); 031 Function<Object, String> toStringFunction = Function.fromFunction(Object::toString, "toString()", 1); 032 return jsf.create(ctx).then(toStringFunction).then(Util.TO_STREAM.create(ctx)); 033 } 034 035 /** 036 * Creates {@link SupplierFactory} of {@link JSONArray} from a list. 037 * The factory is aware of model classes in Ncore package. Model elements 038 * of unknown classes are adapted to SupplierFactory. 039 * @return 040 */ 041 public static SupplierFactory<JSONArray> createJsonArraySupplierFactory(org.nasdanika.ncore.List list) { 042 ListCompoundSupplierFactory<Object> elementsFactory = new ListCompoundSupplierFactory<>("Elements"); 043 for (EObject element: list.getValue()) { 044 if (element instanceof org.nasdanika.ncore.List) { 045 elementsFactory.add(createJsonArraySupplierFactory((org.nasdanika.ncore.List) element)); 046 } else if (element instanceof org.nasdanika.ncore.Map) { 047 elementsFactory.add(createJsonObjectSupplierFactory((org.nasdanika.ncore.Map) element)); 048 } else if (element instanceof org.nasdanika.ncore.Boolean) { 049 elementsFactory.add(SupplierFactory.from(((org.nasdanika.ncore.Boolean) element).getValue(), "Boolean")); 050 } else if (element instanceof org.nasdanika.ncore.Integer) { 051 elementsFactory.add(SupplierFactory.from(((org.nasdanika.ncore.Integer) element).getValue(), "Integer")); 052 } else if (element instanceof org.nasdanika.ncore.String) { 053 elementsFactory.add(SupplierFactory.from(((org.nasdanika.ncore.String) element).getValue(), "String")); 054 } else { 055 elementsFactory.add(adaptToSupplierFactory(element)); 056 } 057 } 058 059 return elementsFactory.then(ListSupplierFactoryAdapter::createListToJsonArrayFunction); 060 } 061 062 /** 063 * Attempts to adapt to {@link Tag} factory first using {@link SupplierFactory.Provider}. Then to InputStream factory and chains with toString factory. 064 * @param obj 065 * @return 066 */ 067 private static SupplierFactory<? extends Object> adaptToSupplierFactory(EObject obj) { 068 Provider provider = EObjectAdaptable.adaptTo(obj, Provider.class); 069 if (provider != null) { 070 SupplierFactory<Tag> tagFactory = provider.getFactory(Tag.class); 071 if (tagFactory != null) { 072 return tagFactory; 073 } 074 075 SupplierFactory<InputStream> streamFactory = provider.getFactory(InputStream.class); 076 if (streamFactory != null) { 077 return streamFactory.then(Util.TO_STRING); 078 } 079 } 080 081 082 return EObjectAdaptable.adaptToSupplierFactoryNonNull(obj, Object.class).then(Util.OBJECT_TO_STRING_FACTORY); 083 } 084 085 private static Function<java.util.List<Object>, JSONArray> createListToJsonArrayFunction(Context context) { 086 return Function.fromFunction(JSONArray::new, "List to JSON array", 1); 087 } 088 089 private static Function<java.util.Map<String, Object>, JSONObject> createMapToJsonObjectFunction(Context context) { 090 java.util.function.Function<Map<String, Object>, JSONObject> func = map -> { 091 return new JSONObject(map); 092 }; 093 return Function.fromFunction(func, "Map to JSON Object", 1); 094 } 095 096 /** 097 * Creates {@link SupplierFactory} of {@link JSONObject} from a map. 098 * The factory is aware of model classes in Ncore package. Model elements 099 * of unknown classes are adapted to SupplierFactory. 100 * @return 101 */ 102 public static SupplierFactory<JSONObject> createJsonObjectSupplierFactory(org.nasdanika.ncore.Map map) { 103 MapCompoundSupplierFactory<String,Object> entryFactory = new MapCompoundSupplierFactory<>("Entries"); 104 for (Property element: map.getValue()) { 105 if (element instanceof org.nasdanika.ncore.ListProperty) { 106 entryFactory.put(element.getName(), createJsonArraySupplierFactory((org.nasdanika.ncore.List) element)); 107 } else if (element instanceof org.nasdanika.ncore.MapProperty) { 108 entryFactory.put(element.getName(),createJsonObjectSupplierFactory((org.nasdanika.ncore.Map) element)); 109 } else if (element instanceof org.nasdanika.ncore.BooleanProperty) { 110 entryFactory.put(element.getName(), SupplierFactory.from(((org.nasdanika.ncore.Boolean) element).getValue(), "Boolean")); 111 } else if (element instanceof org.nasdanika.ncore.IntegerProperty) { 112 entryFactory.put(element.getName(), SupplierFactory.from(((org.nasdanika.ncore.Integer) element).getValue(), "Integer")); 113 } else if (element instanceof org.nasdanika.ncore.StringProperty) { 114 entryFactory.put(element.getName(), SupplierFactory.from(((org.nasdanika.ncore.String) element).getValue(), "String")); 115 } else if (element instanceof EObjectProperty) { 116 entryFactory.put(element.getName(), adaptToSupplierFactory(((EObjectProperty) element).getValue())); 117 } else { 118 throw new UnsupportedOperationException("Unsupported property type: " + element); 119 } 120 } 121 122 return entryFactory.then(ListSupplierFactoryAdapter::createMapToJsonObjectFunction); 123 } 124// 125// /** 126// * Creates {@link SupplierFactory} of {@link BiSupplier} from a property. 127// * The factory is aware of model classes in Ncore package. Model elements 128// * of unknown classes are adapted to SupplierFactory assuming that the result is InputStream. 129// * @return 130// */ 131// public static SupplierFactory<BiSupplier<String, Object>> createPropertySupplierFactory(org.nasdanika.ncore.Property property) { 132// throw new UnsupportedOperationException(); 133// } 134 135} 136