/* * Copyright 2013 cruxframework.org. * * 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 org.cruxframework.crux.core.rebind.database.idb; import java.io.PrintWriter; import java.util.Set; import org.cruxframework.crux.core.client.db.Cursor; import org.cruxframework.crux.core.client.db.Cursor.CursorDirection; import org.cruxframework.crux.core.client.db.DatabaseCursorCallback; import org.cruxframework.crux.core.client.db.DatabaseDeleteCallback; import org.cruxframework.crux.core.client.db.DatabaseRetrieveCallback; import org.cruxframework.crux.core.client.db.DatabaseWriteCallback; import org.cruxframework.crux.core.client.db.IDXAbstractObjectStore; import org.cruxframework.crux.core.client.db.IDXCursor; import org.cruxframework.crux.core.client.db.IDXKeyRange; import org.cruxframework.crux.core.client.db.KeyRangeFactory; import org.cruxframework.crux.core.client.db.indexeddb.IDBObjectStore; import org.cruxframework.crux.core.client.db.indexeddb.IDBObjectStore.IDBObjectCursorRequest; import org.cruxframework.crux.core.client.db.indexeddb.IDBObjectStore.IDBObjectDeleteRequest; import org.cruxframework.crux.core.client.db.indexeddb.IDBObjectStore.IDBObjectRetrieveRequest; import org.cruxframework.crux.core.client.db.indexeddb.IDBObjectStore.IDBObjectStoreRequest; import org.cruxframework.crux.core.client.db.indexeddb.events.IDBCursorEvent; import org.cruxframework.crux.core.client.db.indexeddb.events.IDBErrorEvent; import org.cruxframework.crux.core.client.db.indexeddb.events.IDBObjectDeleteEvent; import org.cruxframework.crux.core.client.db.indexeddb.events.IDBObjectRetrieveEvent; import org.cruxframework.crux.core.client.db.indexeddb.events.IDBObjectStoreEvent; import org.cruxframework.crux.core.client.utils.EscapeUtils; import org.cruxframework.crux.core.client.utils.StringUtils; import org.cruxframework.crux.core.rebind.CruxGeneratorException; import org.cruxframework.crux.core.rebind.context.RebindContext; import org.cruxframework.crux.core.rebind.database.AbstractDatabaseProxyCreator.IndexData; import com.google.gwt.core.ext.typeinfo.JClassType; import com.google.gwt.json.client.JSONObject; import com.google.gwt.user.rebind.ClassSourceFileComposerFactory; /** * @author Thiago da Rosa de Bustamante * */ public class IDBObjectStoreProxyCreator extends IDBAbstractKeyValueProxyCreator { private JClassType abstractObjectStoreType; private String idbObjectStoreVariable; private String dbVariable; private final Set<IndexData> indexes; public IDBObjectStoreProxyCreator(RebindContext context, JClassType targetObjectType, String objectStoreName, String[] keyPath, Set<IndexData> indexes) { super(context, targetObjectType, objectStoreName, keyPath); validatePrimaryKeyPath(targetObjectType, objectStoreName, keyPath); this.indexes = indexes; this.abstractObjectStoreType = context.getGeneratorContext().getTypeOracle().findType(IDXAbstractObjectStore.class.getCanonicalName()); this.idbObjectStoreVariable = "idbObjectStore"; this.dbVariable = "db"; } @Override protected void generateProxyContructor(SourcePrinter srcWriter) throws CruxGeneratorException { srcWriter.println("public "+getProxySimpleName()+"(IDXAbstractDatabase db, IDBObjectStore idbObjectStore){"); srcWriter.println("super(db, idbObjectStore);"); srcWriter.println("}"); } @Override protected void generateProxyMethods(SourcePrinter srcWriter) throws CruxGeneratorException { generateGetObjectStoreNameMethod(srcWriter); generateDeleteMethod(srcWriter); generateDeleteRangeMethod(srcWriter); generateAddMethod(srcWriter); generatePutMethod(srcWriter); generateGetMethod(srcWriter); generateOpenCursorMethod(srcWriter); generateOpenCursorKeyMethod(srcWriter); generateOpenCursorKeyDirectionMethod(srcWriter); generateGetIndexMethod(srcWriter); generateGetKeyRangeFactoryMethod(srcWriter, objectStoreName); if (hasCompositeKey()) { generateGetNativeKeyMethod(srcWriter); } } protected void generateGetObjectStoreNameMethod(SourcePrinter srcWriter) { srcWriter.println("public String getObjectStoreName(){"); srcWriter.println("return "+EscapeUtils.quote(objectStoreName)+";"); srcWriter.println("}"); srcWriter.println(); } protected void generateDeleteMethod(SourcePrinter srcWriter) { srcWriter.println("public void delete("+getKeyTypeName()+" key, final DatabaseDeleteCallback callback){"); if (hasCompositeKey()) { srcWriter.println("IDBObjectDeleteRequest deleteRequest = " + idbObjectStoreVariable+".delete(getNativeKey(key));"); } else { srcWriter.println("IDBObjectDeleteRequest deleteRequest = " + idbObjectStoreVariable+".delete(key);"); } generateDeleteCallbacks(srcWriter, "callback", dbVariable, "deleteRequest"); srcWriter.println("}"); srcWriter.println(); } protected void generateDeleteRangeMethod(SourcePrinter srcWriter) { srcWriter.println("public void delete(KeyRange<"+getKeyTypeName()+"> keyRange, final DatabaseDeleteCallback callback){"); srcWriter.println("IDBObjectDeleteRequest deleteRequest = " + idbObjectStoreVariable+".delete("+IDXKeyRange.class.getCanonicalName()+".getNativeKeyRange(keyRange));"); generateDeleteCallbacks(srcWriter, "callback", dbVariable, "deleteRequest"); srcWriter.println("}"); srcWriter.println(); } protected void generateAddMethod(SourcePrinter srcWriter) { srcWriter.println("public void add("+getTargetObjectClassName()+" object){"); srcWriter.println("add(object, null);"); srcWriter.println("}"); srcWriter.println(); srcWriter.println("public void add("+getTargetObjectClassName()+" object, final DatabaseWriteCallback<"+getKeyTypeName()+"> callback){"); srcWriter.println("if (object == null){"); srcWriter.println("throw new NullPointerException();"); srcWriter.println("}"); if (isEmptyType()) { srcWriter.println("IDBObjectStoreRequest storeRequest = " + idbObjectStoreVariable+".add(object);"); } else { srcWriter.println("IDBObjectStoreRequest storeRequest = " + idbObjectStoreVariable+".add("+serializerVariable+".encode(object).isObject().getJavaScriptObject());"); } generateWriteCallbacks(srcWriter, "callback", dbVariable, "storeRequest"); srcWriter.println("}"); srcWriter.println(); } protected void generatePutMethod(SourcePrinter srcWriter) { srcWriter.println("public void put("+getTargetObjectClassName()+" object){"); srcWriter.println("put(object, null);"); srcWriter.println("}"); srcWriter.println(); srcWriter.println("public void put("+getTargetObjectClassName()+" object, final DatabaseWriteCallback<"+getKeyTypeName()+"> callback){"); srcWriter.println("if (object == null){"); srcWriter.println("throw new NullPointerException();"); srcWriter.println("}"); if (isEmptyType()) { srcWriter.println("IDBObjectStoreRequest storeRequest = " + idbObjectStoreVariable+".put(object);"); } else { srcWriter.println("IDBObjectStoreRequest storeRequest = " + idbObjectStoreVariable+".put("+serializerVariable+".encode(object).isObject().getJavaScriptObject());"); } generateWriteCallbacks(srcWriter, "callback", dbVariable, "storeRequest"); srcWriter.println("}"); srcWriter.println(); } protected void generateGetMethod(SourcePrinter srcWriter) { srcWriter.println("public void get("+getKeyTypeName()+" key, final DatabaseRetrieveCallback<"+getTargetObjectClassName()+"> callback){"); if (hasCompositeKey()) { srcWriter.println("IDBObjectRetrieveRequest retrieveRequest = "+idbObjectStoreVariable+".get(getNativeKey(key));"); } else { srcWriter.println("IDBObjectRetrieveRequest retrieveRequest = "+idbObjectStoreVariable+".get(key);"); } generateGetCallbacks(srcWriter, "callback", dbVariable, "retrieveRequest"); srcWriter.println("}"); srcWriter.println(); } protected void generateOpenCursorMethod(SourcePrinter srcWriter) { srcWriter.println("public void openCursor(final DatabaseCursorCallback<"+getKeyTypeName()+", "+getTargetObjectClassName()+"> callback){"); srcWriter.println("IDBObjectCursorRequest cursorRequest = " + idbObjectStoreVariable+".openCursor();"); generateCursorHandlers(srcWriter, "callback", dbVariable, "cursorRequest", "ObjectStore_"+getTargetObjectClassName()); srcWriter.println("}"); srcWriter.println(); } protected void generateOpenCursorKeyMethod(SourcePrinter srcWriter) { srcWriter.println("public void openCursor(KeyRange<"+getKeyTypeName()+"> keyRange, final DatabaseCursorCallback<"+getKeyTypeName()+", "+getTargetObjectClassName()+"> callback){"); srcWriter.println("IDBObjectCursorRequest cursorRequest = " + idbObjectStoreVariable+".openCursor("+IDXKeyRange.class.getCanonicalName()+".getNativeKeyRange(keyRange));"); generateCursorHandlers(srcWriter, "callback", dbVariable, "cursorRequest", "ObjectStore_"+getTargetObjectClassName()); srcWriter.println("}"); srcWriter.println(); } protected void generateOpenCursorKeyDirectionMethod(SourcePrinter srcWriter) { srcWriter.println("public void openCursor(KeyRange<"+getKeyTypeName()+"> keyRange, CursorDirection direction, final DatabaseCursorCallback<"+getKeyTypeName()+", "+getTargetObjectClassName()+"> callback){"); srcWriter.println("IDBObjectCursorRequest cursorRequest = " + idbObjectStoreVariable+".openCursor("+IDXKeyRange.class.getCanonicalName()+".getNativeKeyRange(keyRange), "+IDXCursor.class.getCanonicalName()+".getNativeCursorDirection(direction));"); generateCursorHandlers(srcWriter, "callback", dbVariable, "cursorRequest", "ObjectStore_"+getTargetObjectClassName()); srcWriter.println("}"); srcWriter.println(); } protected void generateGetIndexMethod(SourcePrinter srcWriter) { srcWriter.println("public <I> Index<"+getKeyTypeName()+", I, "+getTargetObjectClassName()+"> getIndex(String name){"); for(IndexData index: indexes) { srcWriter.println("if (StringUtils.unsafeEquals(name, "+EscapeUtils.quote(index.indexName)+")){"); String indexClassName = new IDBIndexProxyCreator(context, targetObjectType, objectStoreName, index.keyPath, index.indexName, keyPath).create(); srcWriter.println("return (Index<"+getKeyTypeName()+", I, "+getTargetObjectClassName()+">) new " + indexClassName + "("+dbVariable+", "+idbObjectStoreVariable+".getIndex(name));"); srcWriter.println("}"); } srcWriter.println("return null;"); srcWriter.println("}"); srcWriter.println(); } @Override public String getProxyQualifiedName() { return abstractObjectStoreType.getPackage().getName()+"."+getProxySimpleName(); } @Override public String getProxySimpleName() { String typeName = objectStoreName.replaceAll("\\W", "_"); return typeName+"_ObjectStore"; } @Override protected SourcePrinter getSourcePrinter() { String packageName = abstractObjectStoreType.getPackage().getName(); PrintWriter printWriter = context.getGeneratorContext().tryCreate(context.getLogger(), packageName, getProxySimpleName()); if (printWriter == null) { return null; } ClassSourceFileComposerFactory composerFactory = new ClassSourceFileComposerFactory(packageName, getProxySimpleName()); String[] imports = getImports(); for (String imp : imports) { composerFactory.addImport(imp); } composerFactory.setSuperclass("IDXAbstractObjectStore<"+getKeyTypeName()+","+getTargetObjectClassName()+">"); return new SourceCodePrinter(composerFactory.createSourceWriter(context.getGeneratorContext(), printWriter), context.getLogger()); } /** * @return */ protected String[] getImports() { String[] imports = new String[] { IDXAbstractObjectStore.class.getCanonicalName(), IDBObjectStore.class.getCanonicalName(), DatabaseRetrieveCallback.class.getCanonicalName(), DatabaseWriteCallback.class.getCanonicalName(), IDBObjectRetrieveEvent.class.getCanonicalName(), IDBObjectRetrieveRequest.class.getCanonicalName(), IDBObjectStoreRequest.class.getCanonicalName(), IDBObjectStoreEvent.class.getCanonicalName(), JSONObject.class.getCanonicalName(), DatabaseCursorCallback.class.getCanonicalName(), IDBObjectCursorRequest.class.getCanonicalName(), IDBCursorEvent.class.getCanonicalName(), IDBErrorEvent.class.getCanonicalName(), KeyRangeFactory.class.getCanonicalName(), Cursor.class.getCanonicalName(), CursorDirection.class.getCanonicalName(), StringUtils.class.getCanonicalName(), DatabaseDeleteCallback.class.getCanonicalName(), IDBObjectDeleteEvent.class.getCanonicalName(), IDBObjectDeleteRequest.class.getCanonicalName() }; return imports; } }