/** * Copyright 2004-2016 Riccardo Solmi. All rights reserved. * This file is part of the Whole Platform. * * The Whole Platform is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * The Whole Platform is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with the Whole Platform. If not, see <http://www.gnu.org/licenses/>. */ package org.whole.lang; import java.io.File; import org.whole.lang.bindings.BindingManagerFactory; import org.whole.lang.bindings.IBindingManager; import org.whole.lang.builders.ModelBuilderOperation; import org.whole.lang.codebase.IPersistenceKit; import org.whole.lang.codebase.StringPersistenceProvider; import org.whole.lang.commons.parsers.CommonsDataTypePersistenceParser; import org.whole.lang.iterators.IEntityIterator; import org.whole.lang.iterators.IteratorFactory; import org.whole.lang.java.codebase.JavaBuilderPersistenceKit; import org.whole.lang.java.util.JavaStoreProducerBuilder; import org.whole.lang.java.util.JavaStoreProducerBuilderOperation; import org.whole.lang.model.IEntity; import org.whole.lang.operations.PrettyPrinterOperation; import org.whole.lang.reflect.AbstractFunctionLibraryDeployer; import org.whole.lang.reflect.IDeployer; import org.whole.lang.reflect.ILanguageKit; import org.whole.lang.reflect.ReflectionFactory; import org.whole.lang.templates.ModelTemplate; import org.whole.lang.util.IRunnable; import org.whole.lang.util.ResourceUtils; import org.whole.lang.util.StringUtils; import org.whole.lang.xml.util.XmlStoreConsumerVisitor; import org.whole.lang.xml.util.XmlStoreProducerBuilder; import org.whole.lang.xml.util.XmlStoreProducerBuilderOperation; import bsh.EvalError; import bsh.Interpreter; /** * @author Riccardo Solmi */ public class PersistenceLibraryDeployer extends AbstractFunctionLibraryDeployer { public static final String URI = "whole:org.whole.lang:PersistenceLibrary"; @Override public int getDeployLevel() { return IDeployer.LEVEL_LANGUAGE_EXTENSION-1;//FIXME workaround } public void deploy(ReflectionFactory platform) { putFunctionLibrary(URI); putFunctionCode("stringToModel", stringToModelIterator()); putFunctionCode("modelToString", modelToStringIterator()); putFunctionCode("toJavaBuilderCompilationUnit", toJavaBuilderCompilationUnit()); putFunctionCode("toJavaBuilderBlock", toJavaBuilderBlock()); putFunctionCode("fromJavaBuilderModel", fromJavaBuilderModel()); putFunctionCode("toXmlBuilderDocument", toXmlBuilderDocument()); putFunctionCode("toXmlBuilderContent", toXmlBuilderContent()); putFunctionCode("fromXmlBuilderModel", fromXmlBuilderModel()); } public static IEntityIterator<IEntity> stringToModelIterator() { return IteratorFactory.singleValuedRunnableIterator( (IEntity selfEntity, IBindingManager bm, IEntity... arguments) -> { StringPersistenceProvider pp = new StringPersistenceProvider(selfEntity.wStringValue()); IPersistenceKit persistenceKit = null; try { persistenceKit = derivePersistenceKit(bm, pp); } catch (Exception e) { throw new IllegalArgumentException("Failed to load the persistence kit", e); } try { bm.setResult(persistenceKit.readModel(pp)); } catch (Exception e) { throw new IllegalArgumentException("Failed to load the resource with the given persistence: " + persistenceKit.getId(), e); } }); } public static IEntityIterator<IEntity> modelToStringIterator() { return IteratorFactory.singleValuedRunnableIterator( (IEntity selfEntity, IBindingManager bm, IEntity... arguments) -> { StringPersistenceProvider pp = new StringPersistenceProvider(); pp.getBindings().wDefValue("entityURI", selfEntity.wGetEntityDescriptor().getURI()); IPersistenceKit persistenceKit = null; try { persistenceKit = derivePersistenceKit(bm, pp); } catch (Exception e) { throw new IllegalArgumentException("Failed to load the persistence kit", e); } try { persistenceKit.writeModel(selfEntity, pp); } catch (Exception e) { throw new IllegalArgumentException("Failed to load the resource with the given persistence: " + persistenceKit.getId(), e); } bm.setResult(BindingManagerFactory.instance.createValue(pp.getStore())); }); } protected static IPersistenceKit derivePersistenceKit(IBindingManager bm, StringPersistenceProvider pp) { String persistenceKitId = null; if (bm.wIsSet("grammarURI")) { pp.getBindings().wDefValue("grammarURI", bm.wStringValue("grammarURI")); persistenceKitId = "org.whole.lang.grammars.codebase.GrammarsPersistenceKit"; } else if (bm.wIsSet("persistenceId")) persistenceKitId = bm.wStringValue("persistenceId"); if (bm.wIsSet("entityURI")) { String entityURI = bm.wStringValue("entityURI"); pp.getBindings().wDefValue("entityURI", entityURI); } if (pp.getBindings().wIsSet("entityURI")) { String entityURI = pp.getBindings().wStringValue("entityURI"); String contextUri = bm.wIsSet("contextURI") ? bm.wStringValue("contextURI") : null; ILanguageKit languageKit = ResourceUtils.hasFragmentPart(entityURI) ? CommonsDataTypePersistenceParser.getEntityDescriptor(entityURI, true, contextUri).getLanguageKit() : ReflectionFactory.getLanguageKit(entityURI, true, contextUri);; if (persistenceKitId == null) for (IPersistenceKit persistenceKit : languageKit.getPersistenceKits()) if (!persistenceKit.isGeneric()) { persistenceKitId = persistenceKit.getId(); break; } if (persistenceKitId == null) persistenceKitId = languageKit.getDefaultPersistenceKit().getId(); } if (persistenceKitId == null) persistenceKitId = "org.whole.lang.xml.codebase.XmlBuilderPersistenceKit"; if (!ReflectionFactory.hasPersistenceKit(persistenceKitId)) throw new IllegalArgumentException("Missing persistence"); return ReflectionFactory.getPersistenceKit(persistenceKitId); } public static IEntityIterator<IEntity> toJavaBuilderCompilationUnit() { return IteratorFactory.singleValuedRunnableIterator(new IRunnable() { public void run(IEntity selfEntity, IBindingManager bm, IEntity... arguments) { if (bm.wIsSet("file")) { Object file = bm.wGetValue("file"); if (file instanceof File) bm.wDefValue("className", StringUtils.stripFileExtension(((File) file).getName())); } if (bm.wIsSet("fileName"))//TODO test was !bm.wIsSet("className") && bm.wDefValue("className", bm.wStringValue("fileName")); IEntity packageNameEntity = bm.wGet("packageName"); String packageName = packageNameEntity != null ? packageNameEntity.wStringValue() : null; IEntity classNameEntity = bm.wGet("className"); String className = classNameEntity != null ? bm.wStringValue("className") : "AnonymousClass"; ModelBuilderOperation op = new ModelBuilderOperation(); JavaStoreProducerBuilderOperation javaOp = new JavaStoreProducerBuilderOperation(op); ((JavaStoreProducerBuilder) javaOp.wGetBuilder()).buildStartCompilationUnit( packageName, className, selfEntity.wGetEntityDescriptor().getEntityType().getName()); new ModelTemplate(selfEntity).apply(javaOp); ((JavaStoreProducerBuilder) javaOp.wGetBuilder()).buildEndCompilationUnit(); bm.setResult(op.wGetResult()); } }); } public static IEntityIterator<IEntity> toJavaBuilderBlock() { return IteratorFactory.singleValuedRunnableIterator(new IRunnable() { public void run(IEntity selfEntity, IBindingManager bm, IEntity... arguments) { ModelBuilderOperation op = new ModelBuilderOperation(); JavaStoreProducerBuilderOperation javaOp = new JavaStoreProducerBuilderOperation(op); ((JavaStoreProducerBuilder) javaOp.wGetBuilder()).buildStartBlock(); new ModelTemplate(selfEntity).apply(javaOp); ((JavaStoreProducerBuilder) javaOp.wGetBuilder()).buildEndBlock(); bm.setResult(op.wGetResult()); } }); } //FIXME public static IEntityIterator<IEntity> fromJavaBuilderModel() { return IteratorFactory.singleValuedRunnableIterator(new IRunnable() { public void run(IEntity selfEntity, IBindingManager bm, IEntity... arguments) { //TODO test selftEntity is a java model String javaText = PrettyPrinterOperation.toPrettyPrintString(selfEntity); Interpreter javaInterpreter = new Interpreter(); javaInterpreter.setClassLoader(ReflectionFactory.getPlatformClassLoader()); try { Object result = javaInterpreter.eval(JavaBuilderPersistenceKit.toBeanShellScript(javaText)); if (result instanceof IEntity) { bm.setResult((IEntity) result); return; } } catch (EvalError e) { } bm.setResultIterator(IteratorFactory.emptyIterator()); } }); } public static IEntityIterator<IEntity> toXmlBuilderDocument() { return IteratorFactory.singleValuedRunnableIterator(new IRunnable() { public void run(IEntity selfEntity, IBindingManager bm, IEntity... arguments) { ModelBuilderOperation op = new ModelBuilderOperation(); XmlStoreProducerBuilderOperation xmlOp = new XmlStoreProducerBuilderOperation(op); ((XmlStoreProducerBuilder) xmlOp.wGetBuilder()).buildStartDocument(); new ModelTemplate(selfEntity).apply(xmlOp); ((XmlStoreProducerBuilder) xmlOp.wGetBuilder()).buildEndDocument(); bm.setResult(op.wGetResult()); } }); } public static IEntityIterator<IEntity> toXmlBuilderContent() { return IteratorFactory.singleValuedRunnableIterator(new IRunnable() { public void run(IEntity selfEntity, IBindingManager bm, IEntity... arguments) { ModelBuilderOperation op = new ModelBuilderOperation(); XmlStoreProducerBuilderOperation xmlOp = new XmlStoreProducerBuilderOperation(op); ((XmlStoreProducerBuilder) xmlOp.wGetBuilder()).buildStartContent(); new ModelTemplate(selfEntity).apply(xmlOp); ((XmlStoreProducerBuilder) xmlOp.wGetBuilder()).buildEndContent(); bm.setResult(op.wGetResult()); } }); } public static IEntityIterator<IEntity> fromXmlBuilderModel() { return IteratorFactory.singleValuedRunnableIterator(new IRunnable() { public void run(IEntity selfEntity, IBindingManager bm, IEntity... arguments) { try { ModelBuilderOperation op = new ModelBuilderOperation().withBindings(bm); new XmlStoreConsumerVisitor(op).visit(selfEntity); bm.setResult(op.wGetResult()); return; } catch (Exception e) { } bm.setResultIterator(IteratorFactory.emptyIterator()); } }); } }