/* * 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.Date; import org.cruxframework.crux.core.client.db.Cursor.CursorDirection; import org.cruxframework.crux.core.client.db.DatabaseCursorCallback; import org.cruxframework.crux.core.client.db.DatabaseRetrieveCallback; import org.cruxframework.crux.core.client.db.IDXAbstractDatabase; import org.cruxframework.crux.core.client.db.IDXCursor; import org.cruxframework.crux.core.client.db.IDXIndex; import org.cruxframework.crux.core.client.db.IDXKeyRange; import org.cruxframework.crux.core.client.db.KeyRange; import org.cruxframework.crux.core.client.db.KeyRangeFactory; import org.cruxframework.crux.core.client.db.indexeddb.IDBCursorWithValue; import org.cruxframework.crux.core.client.db.indexeddb.IDBIndex; import org.cruxframework.crux.core.client.db.indexeddb.IDBIndex.IDBIndexCursorRequest; 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.IDBObjectRetrieveEvent; import org.cruxframework.crux.core.client.db.indexeddb.events.IDBObjectStoreEvent; import org.cruxframework.crux.core.rebind.CruxGeneratorException; import org.cruxframework.crux.core.rebind.context.RebindContext; import org.cruxframework.crux.core.server.Environment; 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 IDBIndexProxyCreator extends IDBAbstractKeyValueProxyCreator { private JClassType indexType; private String idbIndexVariable; private String indexName; private String dbVariable; private String[] objectStoreKeyPath; public IDBIndexProxyCreator(RebindContext context, JClassType targetObjectType, String objectStoreName, String[] keyPath, String indexName, String[] objectStoreKeyPath) { super(context, targetObjectType, objectStoreName, keyPath); this.objectStoreKeyPath = objectStoreKeyPath; this.indexType = context.getGeneratorContext().getTypeOracle().findType(IDXIndex.class.getCanonicalName()); this.idbIndexVariable = "idbIndex"; this.dbVariable = "db"; this.indexName = indexName; } @Override protected void generateProxyContructor(SourcePrinter srcWriter) throws CruxGeneratorException { srcWriter.println("public "+getProxySimpleName()+"(IDXAbstractDatabase db, IDBIndex idbIndex){"); srcWriter.println("super(db, idbIndex);"); srcWriter.println("}"); } @Override protected void generateProxyMethods(SourcePrinter srcWriter) throws CruxGeneratorException { generateGetMethod(srcWriter); generateGetRangetMethod(srcWriter); generateGetKeyMethod(srcWriter); generateGetKeyRangetMethod(srcWriter); generateOpenCursorMethod(srcWriter); generateOpenCursorKeyMethod(srcWriter); generateOpenCursorKeyDirectionMethod(srcWriter); generateOpenKeyCursorMethod(srcWriter); generateOpenKeyCursorKeyMethod(srcWriter); generateOpenKeyCursorKeyDirectionMethod(srcWriter); generateGetKeyRangeFactoryMethod(srcWriter, getIndexClassName()); if (hasCompositeKey()) { generateGetNativeKeyMethod(srcWriter); generateFromNativeKeyMethod(srcWriter, objectStoreKeyPath); } } protected void generateGetMethod(SourcePrinter srcWriter) { String keyTypeName = getKeyTypeName(); String targetObjectClassName = getTargetObjectClassName(); srcWriter.println("public void get("+keyTypeName+" key, final DatabaseRetrieveCallback<"+targetObjectClassName+"> callback){"); if (hasCompositeKey()) { srcWriter.println("IDBObjectRetrieveRequest retrieveRequest = "+idbIndexVariable+".get(getNativeKey(key));"); } else { srcWriter.println("IDBObjectRetrieveRequest retrieveRequest = "+idbIndexVariable+".get(key);"); } generateGetCallbacks(srcWriter, "callback", dbVariable, "retrieveRequest"); srcWriter.println("}"); srcWriter.println(); } protected void generateGetRangetMethod(SourcePrinter srcWriter) { String keyTypeName = getKeyTypeName(); String targetObjectClassName = getTargetObjectClassName(); srcWriter.println("public void get(KeyRange<"+keyTypeName+"> keyRange, final DatabaseRetrieveCallback<"+targetObjectClassName+"> callback){"); srcWriter.println("IDBObjectRetrieveRequest retrieveRequest = "+idbIndexVariable+".get("+IDXKeyRange.class.getCanonicalName()+".getNativeKeyRange(keyRange));"); generateGetCallbacks(srcWriter, "callback", dbVariable, "retrieveRequest"); srcWriter.println("}"); srcWriter.println(); } protected void generateGetKeyMethod(SourcePrinter srcWriter) { String keyTypeName = getKeyTypeName(); srcWriter.println("public void getKey("+keyTypeName+" key, final DatabaseRetrieveCallback<"+getKeyTypeName(objectStoreKeyPath)+"> callback){"); if (hasCompositeKey()) { srcWriter.println("IDBObjectStoreRequest retrieveRequest = "+idbIndexVariable+".getKey(getNativeKey(key));"); } else { srcWriter.println("IDBObjectStoreRequest retrieveRequest = "+idbIndexVariable+".getKey(key);"); } generateGetKeyCallbacks(srcWriter, "callback", dbVariable, "retrieveRequest"); srcWriter.println("}"); srcWriter.println(); } protected void generateGetKeyRangetMethod(SourcePrinter srcWriter) { String keyTypeName = getKeyTypeName(); srcWriter.println("public void getKey(KeyRange<"+keyTypeName+"> keyRange, final DatabaseRetrieveCallback<"+getKeyTypeName(objectStoreKeyPath)+"> callback){"); srcWriter.println("IDBObjectStoreRequest retrieveRequest = "+idbIndexVariable+".getKey("+IDXKeyRange.class.getCanonicalName()+".getNativeKeyRange(keyRange));"); generateGetKeyCallbacks(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("IDBIndexCursorRequest cursorRequest = " + idbIndexVariable+".openCursor();"); generateCursorHandlers(srcWriter, "callback", dbVariable, "cursorRequest", getIndexClassName()); srcWriter.println("}"); srcWriter.println(); } protected void generateOpenCursorKeyMethod(SourcePrinter srcWriter) { srcWriter.println("public void openCursor(KeyRange<"+getKeyTypeName()+"> keyRange, final DatabaseCursorCallback<"+getKeyTypeName()+", "+getTargetObjectClassName()+"> callback){"); srcWriter.println("IDBIndexCursorRequest cursorRequest = " + idbIndexVariable+".openCursor("+IDXKeyRange.class.getCanonicalName()+".getNativeKeyRange(keyRange));"); generateCursorHandlers(srcWriter, "callback", dbVariable, "cursorRequest", getIndexClassName()); 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("IDBIndexCursorRequest cursorRequest = " + idbIndexVariable+".openCursor("+IDXKeyRange.class.getCanonicalName()+".getNativeKeyRange(keyRange), "+IDXCursor.class.getCanonicalName()+".getNativeCursorDirection(direction));"); generateCursorHandlers(srcWriter, "callback", dbVariable, "cursorRequest", getIndexClassName()); srcWriter.println("}"); srcWriter.println(); } protected void generateOpenKeyCursorMethod(SourcePrinter srcWriter) { srcWriter.println("public void openKeyCursor(final DatabaseCursorCallback<"+getKeyTypeName()+", "+getKeyTypeName(objectStoreKeyPath)+"> callback){"); srcWriter.println("IDBIndexCursorRequest cursorRequest = " + idbIndexVariable+".openKeyCursor();"); generateKeyCursorHandlers(srcWriter, "callback", dbVariable, "cursorRequest"); srcWriter.println("}"); srcWriter.println(); } protected void generateOpenKeyCursorKeyMethod(SourcePrinter srcWriter) { srcWriter.println("public void openKeyCursor(KeyRange<"+getKeyTypeName()+"> keyRange, final DatabaseCursorCallback<"+getKeyTypeName()+", "+getKeyTypeName(objectStoreKeyPath)+"> callback){"); srcWriter.println("IDBIndexCursorRequest cursorRequest = " + idbIndexVariable+".openKeyCursor("+IDXKeyRange.class.getCanonicalName()+".getNativeKeyRange(keyRange));"); generateKeyCursorHandlers(srcWriter, "callback", dbVariable, "cursorRequest"); srcWriter.println("}"); srcWriter.println(); } protected void generateOpenKeyCursorKeyDirectionMethod(SourcePrinter srcWriter) { srcWriter.println("public void openKeyCursor(KeyRange<"+getKeyTypeName()+"> keyRange, CursorDirection direction, final DatabaseCursorCallback<"+getKeyTypeName()+", "+getKeyTypeName(objectStoreKeyPath)+"> callback){"); srcWriter.println("IDBIndexCursorRequest cursorRequest = " + idbIndexVariable+".openKeyCursor("+IDXKeyRange.class.getCanonicalName()+".getNativeKeyRange(keyRange), "+IDXCursor.class.getCanonicalName()+".getNativeCursorDirection(direction));"); generateKeyCursorHandlers(srcWriter, "callback", dbVariable, "cursorRequest"); srcWriter.println("}"); srcWriter.println(); } protected void generateKeyCursorHandlers(SourcePrinter srcWriter, String callbackVar, String dbVariable, String cursorRequestVar) { srcWriter.println("if ("+callbackVar+" != null || "+dbVariable+".errorHandler != null){"); srcWriter.println("if ("+callbackVar+" != null){"); srcWriter.println(""+callbackVar+".setDb("+dbVariable+");"); srcWriter.println("}"); srcWriter.println(cursorRequestVar+".onSuccess(new IDBCursorEvent.Handler(){"); srcWriter.println("public void onSuccess(IDBCursorEvent event){"); String cursorClassName = new IDBKeyCursorProxyCreator(context, targetObjectType, objectStoreName, keyPath, objectStoreKeyPath, getIndexClassName()).create(); srcWriter.println(IDBCursorWithValue.class.getCanonicalName()+" cursor = event.getCursor();"); srcWriter.println("if ("+callbackVar+" != null){"); if (!Environment.isProduction()) { srcWriter.println("try{"); } srcWriter.println("if(cursor != null){"); srcWriter.println(""+callbackVar+".onSuccess(new "+cursorClassName+"(cursor));"); srcWriter.println("}else{"); srcWriter.println(""+callbackVar+".onSuccess(null);"); srcWriter.println("}"); srcWriter.println(""+callbackVar+".setDb(null);"); if (!Environment.isProduction()) { srcWriter.println("}catch (Exception e){"); srcWriter.println("reportError("+callbackVar+", "+dbVariable+".messages.objectStoreCursorError(e.getMessage()), e);"); srcWriter.println("}"); } srcWriter.println("}"); srcWriter.println("}"); srcWriter.println("});"); //TODO ver possibiliade de aceitar date como chave srcWriter.println(cursorRequestVar+".onError(new IDBErrorEvent.Handler(){"); srcWriter.println("public void onError(IDBErrorEvent event){"); srcWriter.println("if ("+callbackVar+" != null){"); srcWriter.println(""+callbackVar+".onError("+dbVariable+".messages.objectStoreCursorError(event.getName()));"); srcWriter.println(""+callbackVar+".setDb(null);"); srcWriter.println("} else if ("+dbVariable+".errorHandler != null){"); srcWriter.println(dbVariable+".errorHandler.onError("+dbVariable+".messages.objectStoreCursorError(event.getName()));"); srcWriter.println("}"); srcWriter.println("}"); srcWriter.println("});"); srcWriter.println("}"); } protected void generateGetKeyCallbacks(SourcePrinter srcWriter, String callbackVar, String dbVariable, String retrieveRequestVar) { srcWriter.println("if ("+callbackVar+" != null || "+dbVariable+".errorHandler != null){"); srcWriter.println("if ("+callbackVar+" != null){"); srcWriter.println(""+callbackVar+".setDb("+dbVariable+");"); srcWriter.println("}"); srcWriter.println(retrieveRequestVar+".onSuccess(new IDBObjectStoreEvent.Handler(){"); srcWriter.println("public void onSuccess(IDBObjectStoreEvent event){"); srcWriter.println("if ("+callbackVar+" != null){"); String keyTypeName = getKeyTypeName(objectStoreKeyPath); if ((objectStoreKeyPath.length > 1) && (!isEmptyType())) { srcWriter.println(callbackVar+".onSuccess(fromNativeKey(event.getObjectKey()));"); } else if (keyTypeName.equals("String")) { srcWriter.println(callbackVar+".onSuccess(event.getStringKey());"); } else if (keyTypeName.equals("Integer")) { srcWriter.println(callbackVar+".onSuccess(event.getIntKey());"); } else if (keyTypeName.equals("Double")) { srcWriter.println(callbackVar+".onSuccess(event.getDoubleKey());"); } else if (keyTypeName.equals(Date.class.getCanonicalName())) { srcWriter.println(callbackVar+".onSuccess(event.getDateKey());"); } else { srcWriter.println(callbackVar+".onSuccess(event.getObjectKey.cast());"); } srcWriter.println(""+callbackVar+".setDb(null);"); srcWriter.println("}"); srcWriter.println("}"); srcWriter.println("});"); srcWriter.println(retrieveRequestVar+".onError(new IDBErrorEvent.Handler(){"); srcWriter.println("public void onError(IDBErrorEvent event){"); srcWriter.println("if ("+callbackVar+" != null){"); srcWriter.println(""+callbackVar+".onError("+dbVariable+".messages.objectStoreGetError(event.getName()));"); srcWriter.println(""+callbackVar+".setDb(null);"); srcWriter.println("} else if ("+dbVariable+".errorHandler != null){"); srcWriter.println(dbVariable+".errorHandler.onError("+dbVariable+".messages.objectStoreGetError(event.getName()));"); srcWriter.println("}"); srcWriter.println("}"); srcWriter.println("});"); srcWriter.println("}"); } @Override public String getProxyQualifiedName() { return indexType.getPackage().getName()+"."+getProxySimpleName(); } @Override public String getProxySimpleName() { return getIndexClassName()+"_Index"; } protected String getIndexClassName() { String typeName = indexName.replaceAll("\\W", "_"); return objectStoreName + "_" + typeName; } @Override protected SourcePrinter getSourcePrinter() { String packageName = indexType.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("IDXIndex<"+getKeyTypeName(objectStoreKeyPath)+","+getKeyTypeName()+","+getTargetObjectClassName()+">"); return new SourceCodePrinter(composerFactory.createSourceWriter(context.getGeneratorContext(), printWriter), context.getLogger()); } protected String[] getImports() { String[] imports = new String[] { IDXIndex.class.getCanonicalName(), IDBIndex.class.getCanonicalName(), IDBObjectRetrieveRequest.class.getCanonicalName(), IDBObjectRetrieveEvent.class.getCanonicalName(), IDBObjectStoreEvent.class.getCanonicalName(), IDBObjectStoreRequest.class.getCanonicalName(), IDBErrorEvent.class.getCanonicalName(), IDBIndexCursorRequest.class.getCanonicalName(), IDBCursorEvent.class.getCanonicalName(), DatabaseRetrieveCallback.class.getCanonicalName(), DatabaseCursorCallback.class.getCanonicalName(), IDXAbstractDatabase.class.getCanonicalName(), KeyRange.class.getCanonicalName(), KeyRangeFactory.class.getCanonicalName(), JSONObject.class.getCanonicalName(), CursorDirection.class.getCanonicalName() }; return imports; } }