/* * Copyright (C) 2012 The Android Open Source Project * * 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 com.motorola.studio.android.codeutils.codegeneration; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.ListIterator; import java.util.Map; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.SubMonitor; import org.eclipse.datatools.modelbase.sql.datatypes.SQLDataType; import org.eclipse.datatools.modelbase.sql.tables.Column; import org.eclipse.datatools.modelbase.sql.tables.Table; import org.eclipse.jface.wizard.IWizardPage; import com.motorola.studio.android.codeutils.CodeUtilsActivator; import com.motorola.studio.android.codeutils.db.utils.DatabaseUtils; import com.motorola.studio.android.codeutils.i18n.CodeUtilsNLS; import com.motorola.studio.android.common.exception.AndroidException; import com.motorola.studio.android.common.log.StudioLogger; import com.motorola.studio.android.common.utilities.EclipseUtils; import com.motorola.studio.android.model.IDatabaseSampleActivityParametersWizardCollector; /** * Helper class to create Activity based on Sqlite tables. * It uses one file as template and substitutes parameters enclosed by hash-sign (#) * Warning: The tables named "ANDROID_METADATA" and "sqlite_sequence" will be ignored as it is an special table in Android apps context. */ public class DatabaseListActivityGeneratorByTable implements IDatabaseSampleActivityParametersWizardCollector { private static final String CLASS_EXTENTION_TYPE = "Activity"; private String databaseName = null; private String sqlOpenHelperClassName = null; private String sqlOpenHelperPackageName = null; private boolean createOpenHelper = false; private Table table = null; private final List<Column> selectedColumns = new ArrayList<Column>(); //includes only items that are not default, that is with the java cursor type varies from the return type private static Map<String, String> SQLTYPE_TO_CURSOR_TYPE_METHOD = new HashMap<String, String>(); private static Map<String, String> SQLTYPE_TO_RETURN_TYPE = new HashMap<String, String>(); static { SQLTYPE_TO_CURSOR_TYPE_METHOD.put("BLOB", "Byte"); SQLTYPE_TO_CURSOR_TYPE_METHOD.put("INTEGER", "Int"); SQLTYPE_TO_RETURN_TYPE.put("CHAR", "String"); SQLTYPE_TO_RETURN_TYPE.put("VARCHAR", "String"); SQLTYPE_TO_RETURN_TYPE.put("TEXT", "String"); SQLTYPE_TO_RETURN_TYPE.put("SMALLINT", "Short"); SQLTYPE_TO_RETURN_TYPE.put("INTEGER", "Integer"); SQLTYPE_TO_RETURN_TYPE.put("BIGINT", "Long"); SQLTYPE_TO_RETURN_TYPE.put("REAL", "Float"); SQLTYPE_TO_RETURN_TYPE.put("FLOAT", "Double"); SQLTYPE_TO_RETURN_TYPE.put("DOUBLE", "Double"); SQLTYPE_TO_RETURN_TYPE.put("BINARY", "byte[]"); SQLTYPE_TO_RETURN_TYPE.put("VARBINARY", "byte[]"); SQLTYPE_TO_RETURN_TYPE.put("LONG VARBINARY", "byte[]"); SQLTYPE_TO_RETURN_TYPE.put("IMAGE", "byte[]"); SQLTYPE_TO_RETURN_TYPE.put("BLOB", "byte[]"); } /** * @return the table created by this class. * */ @Override public Table getTable() { return this.table; } /** * Sets the initial table to be used. * */ @Override public void setTable(Table table) { this.table = table; } @Override public String getTableName() { return getTable().getName(); } /** * Authority to access content URI (it is based on package name and content provider name) * @param packageName the package name of the authority. * @param activityName the activity name of the authority. * @return the authority using package and activity name. */ protected String getAuthority(String packageName, String activityName) { return packageName + "." + activityName.toLowerCase(); } public String getClassName() { String className = getTableName() + CLASS_EXTENTION_TYPE; return className; } @Override public String getDatabaseName() { return this.databaseName; } @Override public void setDatabaseName(String databaseName) { this.databaseName = databaseName; } /** * @return a string representing a list of the column names. */ @Override public String getColumnsNames() { StringBuilder buf = new StringBuilder(); String columnsResult = ""; for (int i = 0; i < selectedColumns.size(); i++) { int colIndex = i + 1; String colSt = "COL_" + colIndex; if ((colIndex > 1) && (colIndex <= selectedColumns.size())) { colSt = ", " + colSt; } columnsResult += colSt; } buf.append(columnsResult); return buf.toString(); } /** * @return constants to get on table list */ @Override public String getConstColumnsNames() { StringBuilder buf = new StringBuilder(); ListIterator<Column> columnsIter = selectedColumns.listIterator(); int index = 1; String constSt = "private final String "; while (columnsIter.hasNext()) { Column column = columnsIter.next(); String colSt = constSt + "COL_" + index + " = " + "\"" + column.getName() + "\";"; buf.append("\t" + colSt + "\n"); index++; } return buf.toString(); } /** * Creates add columns * @throws AndroidException when the type of a column is not valid. */ @Override public String getCursorValues() throws AndroidException { StringBuilder buf = new StringBuilder(); ListIterator<Column> columnsIter = selectedColumns.listIterator(); Integer index = 1; String templateSt = "#returnType# col#index# = cursor.get#CursorType#(cursor.getColumnIndex(COL_#index#));"; while (columnsIter.hasNext()) { String cursorSt = templateSt; Column column = columnsIter.next(); String columnName = column.getName().toLowerCase(); String sqltype = null; SQLDataType type = column.getContainedType(); if (type != null) { sqltype = type.getName(); } else { throw new AndroidException("Column " + columnName + " does not have a recognized type"); } String javaReturnType = SQLTYPE_TO_RETURN_TYPE.get(sqltype); cursorSt = cursorSt.replace("#returnType#", javaReturnType); cursorSt = cursorSt.replaceAll("#index#", index.toString()); String getType = ""; if (SQLTYPE_TO_CURSOR_TYPE_METHOD.containsKey(sqltype)) { //non-default rule getType = SQLTYPE_TO_CURSOR_TYPE_METHOD.get(sqltype); } else { //default rule - getX where X is the java type getType = SQLTYPE_TO_RETURN_TYPE.get(sqltype); getType = getType.replace("[]", ""); //change first letter to upper case String firstElem = "" + getType.charAt(0); getType = getType.replace(firstElem, firstElem.toUpperCase()); } cursorSt = cursorSt.replaceAll("#CursorType#", getType); index++; buf.append("\t" + cursorSt + "\n"); } return buf.toString(); } /** * Creates add columns to row statements */ @Override public String getAddColumnsToRow() { StringBuilder buf = new StringBuilder(); String constSt = "addToRow(col#index# , row);"; for (int i = 0; i < selectedColumns.size(); i++) { String replacedText = constSt.replace("#index#", Integer.toString(i + 1)); buf.append("\t" + replacedText + "\n"); } return buf.toString(); } /** * @return a list of wizard pages required to create activities based on database list templates. * */ @Override public List<IWizardPage> getWizardPages() { List<IWizardPage> contributedPages = new ArrayList<IWizardPage>(); contributedPages.add(new CreateSampleDatabaseActivityPage()); contributedPages.add(new CreateSampleDatabaseActivityColumnsPage()); contributedPages.add(new DefineSqlOpenHelperPage()); return contributedPages; } @Override public void setSelectedColumns(List<Column> selectedColumns) { this.selectedColumns.addAll(selectedColumns); } /** * Creates Sql Open Helper required to transfer db file and make the activity work correctly */ @Override public void createSqlOpenHelper(IProject project, IProgressMonitor monitor) { boolean createOpenHelper = true; boolean createContentProvider = false; boolean isOverrideContentProviders = false; boolean generateDao = false; String contentProvidersPackageName = null; //not used //create deployer try { // sub monitor SubMonitor subMonitor = SubMonitor.convert(monitor, 10); DatabaseUtils.createDatabaseManagementClasses(project, databaseName, createOpenHelper, createContentProvider, sqlOpenHelperPackageName, contentProvidersPackageName, getSqlOpenHelperClassName(), isOverrideContentProviders, generateDao, subMonitor.newChild(10), false); } catch (Exception e) { StudioLogger.error(DatabaseListActivityGeneratorByTable.class, CodeUtilsNLS.DATABASE_DEPLOY_ERROR_DEPLOYING_DATABASE, e); IStatus status = new Status(IStatus.ERROR, CodeUtilsActivator.PLUGIN_ID, e.getLocalizedMessage()); EclipseUtils.showErrorDialog(CodeUtilsNLS.DATABASE_DEPLOY_ERROR_DEPLOYING_DATABASE, CodeUtilsNLS.DATABASE_DEPLOY_ERROR_DEPLOYING_DATABASE, status); } } @Override public String getSqlOpenHelperClassName() { return this.sqlOpenHelperClassName; } @Override public void setSqlOpenHelperClassName(String sqlOpenHelperClassName) { this.sqlOpenHelperClassName = sqlOpenHelperClassName; } @Override public void setSqlOpenHelperPackageName(String sqlOpenHelperPackageName) { this.sqlOpenHelperPackageName = sqlOpenHelperPackageName; } /** * @return The fully qualified name of the generated class to be used as {@code import} statement. * */ @Override public String getImports() { String imports = ""; if (createOpenHelper) { imports = "import " + this.sqlOpenHelperPackageName + "." + this.sqlOpenHelperClassName + ";"; } return imports; } /** * @return True if the open helper classes will be created. Otherwise, returns false. * */ @Override public boolean createOpenHelper() { return this.createOpenHelper; } /** * Set whether the open helper classes should be created. * */ @Override public void setCreateOpenHelper(boolean createOpenHelper) { this.createOpenHelper = createOpenHelper; } /** * @return A string representing the necessary code to retrieve an android readable database of the database created in this class. * */ @Override public String getReadableDatabase() { StringBuilder buf = new StringBuilder(); if (createOpenHelper) { buf.append(sqlOpenHelperClassName + " helper = new " + sqlOpenHelperClassName + "(getApplicationContext(),true);" + "\n"); buf.append("checkDB = helper.getReadableDatabase();" + "\n"); } else { buf.append("String myPath = DB_PATH + DB_NAME;" + "\n"); buf.append("checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);" + "\n"); } return buf.toString(); } }