/************************************************************************ * Copyright (c) 2016 IoT-Solutions e.U. * * Licensed 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 iot.jcypher.domainquery; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Map.Entry; import iot.jcypher.database.IDBAccess; import iot.jcypher.domain.IDomainAccess; import iot.jcypher.domain.IGenericDomainAccess; import iot.jcypher.domain.internal.IIntDomainAccess; import iot.jcypher.domainquery.api.APIAccess; import iot.jcypher.domainquery.api.DomainObjectMatch; import iot.jcypher.domainquery.internal.JSONConverter; import iot.jcypher.domainquery.internal.QueryExecutor; import iot.jcypher.domainquery.internal.RecordedQuery; import iot.jcypher.domainquery.internal.RecordedQueryPlayer; import iot.jcypher.domainquery.internal.ReplayedQueryContext; import iot.jcypher.graph.GrNode; import iot.jcypher.query.JcQuery; import iot.jcypher.query.JcQueryResult; import iot.jcypher.query.api.IClause; import iot.jcypher.query.factories.clause.MATCH; import iot.jcypher.query.factories.clause.RETURN; import iot.jcypher.query.values.JcNode; import iot.jcypher.util.Util; public class QueryLoader<T> { private Object domainAccess; // can be IDomainAccess or IGenericDomainAccess private String queryName; private ReplayedQueryContext replayedQueryContext; QueryLoader( String qName, Object domAccess) { this.queryName = qName; this.domainAccess = domAccess; } @SuppressWarnings("unchecked") public T load() { QueryMemento qm = loadMemento(); if (qm != null) { RecordedQuery rq = new JSONConverter().fromJSON(qm.getQueryJSON()); RecordedQueryPlayer qp = new RecordedQueryPlayer(true); // create new T q; if (isGeneric()) q = (T) qp.replayGenericQuery(rq, (IGenericDomainAccess) this.domainAccess); else q = (T) qp.replayQuery(rq, (IDomainAccess) this.domainAccess); this.replayedQueryContext = ((AbstractDomainQuery) q).getReplayedQueryContext(); QueryExecutor qe = InternalAccess.getQueryExecutor((AbstractDomainQuery) q); qe.queryCreationCompleted(true); // delete the replayedQueryContext return q; } return null; } /** * The memento contains a JSON representation of the query as well as a Java-DSL like string representation. * @return */ public QueryMemento loadMemento() { IDBAccess dbAccess = ((IIntDomainAccess)this.domainAccess).getInternalDomainAccess().getDBAccess(); String qLabel = ((IIntDomainAccess)this.domainAccess).getInternalDomainAccess().getDomainLabel() .concat(QueryPersistor.Q_LABEL_POSTFIX); JcNode n = new JcNode("n"); IClause[] clauses = new IClause[] { MATCH.node(n).label(qLabel).property(QueryPersistor.PROP_NAME).value(queryName), RETURN.value(n) }; JcQuery q = new JcQuery(); q.setClauses(clauses); JcQueryResult result = dbAccess.execute(q); if (result.hasErrors()) { StringBuilder sb = new StringBuilder(); Util.appendErrorList(Util.collectErrors(result), sb); throw new RuntimeException(sb.toString()); } List<GrNode> lgn = result.resultOf(n); if (lgn.size() > 0) { GrNode gn = lgn.get(0); String qJava = gn.getProperty(QueryPersistor.PROP_Q_JAVA).getValue().toString(); String qJSON = gn.getProperty(QueryPersistor.PROP_Q_JSON).getValue().toString(); QueryMemento qm = new QueryMemento(qJava, qJSON); return qm; } return null; } public List<String> getAugmentedDOMNames() { List<String> dNames; if (this.replayedQueryContext.getRecordedQuery().getAugmentations() != null) { dNames = new ArrayList<String>( this.replayedQueryContext.getRecordedQuery().getAugmentations().values()); Collections.sort(dNames); } else dNames = Collections.emptyList(); return dNames; } public List<String> getInternalDOMNames() { List<String> dNames = new ArrayList<String>( replayedQueryContext.getId2DomainObjectMatch().keySet()); Collections.sort(dNames); return dNames; } public DomainObjectMatch<?> getDomainObjectMatch(String name) { DomainObjectMatch<?> ret = null; if (this.replayedQueryContext.getRecordedQuery().getAugmentations() != null) { Iterator<Entry<String, String>> it = this.replayedQueryContext.getRecordedQuery().getAugmentations().entrySet().iterator(); while(it.hasNext()) { Entry<String, String> entry = it.next(); if (entry.getValue().equals(name)) { ret = this.replayedQueryContext.getById(entry.getKey()); break; } } } if (ret == null) { ret = this.replayedQueryContext.getById(name); } return ret; } @SuppressWarnings("unchecked") public <E> DomainObjectMatch<E> getDomainObjectMatch(String name, Class<E> type) { DomainObjectMatch<?> dom = this.getDomainObjectMatch(name); Class<?> typ = APIAccess.getDomainObjectType(dom); if (!type.isAssignableFrom(typ)) throw new ClassCastException(); return (DomainObjectMatch<E>) dom; } private boolean isGeneric() { return this.domainAccess instanceof IGenericDomainAccess; } }