package com.applang.components; import java.awt.Dimension; import java.io.File; import java.util.ArrayList; import javax.swing.JScrollPane; import javax.swing.JTable; import org.gjt.sp.jedit.BeanShell; import org.gjt.sp.jedit.View; import org.gjt.sp.jedit.bsh.NameSpace; import org.gjt.sp.jedit.bsh.UtilEvalError; import org.w3c.dom.Element; import android.app.AlertDialog; import android.content.ContentResolver; import android.content.ContentUris; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.net.Uri; import com.applang.berichtsheft.BerichtsheftActivity; import com.applang.berichtsheft.plugin.BerichtsheftPlugin; import com.applang.components.DataView.DataModel; import static com.applang.Util.*; import static com.applang.Util1.*; import static com.applang.Util2.*; import static com.applang.SwingUtil.*; import static com.applang.PluginUtils.*; public class DataAdapter { private Context context; public Context getContext() { return context; } private ContentResolver contentResolver; public DataAdapter(DataView dv) { this(dv.getUriString()); } public DataAdapter(String uriString) { this(BerichtsheftActivity.getInstance(), uriString); } public DataAdapter(String flavor, final File dbFile, String uriString) { this(Context.contextForFlavor(BerichtsheftActivity.packageName, flavor, dbFile), uriString); } private DataAdapter(Context context, String uriString) { this.context = context; contentResolver = context.getContentResolver(); tableName = dbTableName(uriString); info = table_info2( context, Uri.parse(uriString), tableName, context.getFlavor()); } private String tableName; public String getTableName() { return tableName; } public ValMap info; public String getFlavor() { return context.getFlavor(); } public Uri makeUri(String uriString) { uriString = stringValueOf(uriString); String flavor = getFlavor(); Uri uri = Uri.parse(uriString); if (flavor == null) return uri; else { Uri curi = contentUri(flavor, tableName); Long id = parseId(null, uri); if (id != null) return ContentUris.appendId(curi.buildUpon(), id).build(); else return curi; } } public Object[][] query(String uriString, String[] columns, Object...params) { Uri uri = makeUri(uriString); String selection = param(null, 0, params); String[] selectionArgs = param(null, 1, params); String sortOrder = param(null, 2, params); try { final ArrayList<Object[]> rows = alist(); Cursor cursor = contentResolver.query(uri, columns, selection, selectionArgs, sortOrder); traverse(cursor, new Job<Cursor>() { public void perform(Cursor c, Object[] params) throws Exception { rows.add(getRow(c).toArray()); } }); return rows.toArray(new Object[0][]); } catch (Exception e) { BerichtsheftPlugin.consoleMessage("dataview.query.message", stringValueOf(uri), e.getMessage()); return null; } } public DataModel query(String uriString, BidiMultiMap projection, Object...params) { String selection = param(null, 0, params); String[] selectionArgs = param(null, 1, params); String sortOrder = param(null, 2, params); Uri uri = makeUri(uriString); try { Cursor cursor = contentResolver.query(uri, toStrings(projection.getKeys()), selection, selectionArgs, sortOrder); return new DataModel() .setProjection(projection) .traverse(cursor); } catch (Exception e) { BerichtsheftPlugin.consoleMessage("dataview.query.message", stringValueOf(uri), e.getMessage()); return null; } } private Object updateOrInsert_query(Uri uri, ValMap profile, BidiMultiMap projection, String pk, ContentValues values, Function<Integer> skipThis) throws UtilEvalError { boolean found = false; if (ProfileManager.transportsLoaded() && profile != null) { Object name = profile.get("name"); Object flavor = profile.get("flavor"); String xpath = "//FLAVOR[@name='" + flavor + "']"; xpath += "/FUNCTION[@name='updateOrInsert-clause' and @profile='" + name + "']"; Element el = selectElement(ProfileManager.transports, xpath); if (el != null) { String script = el.getTextContent(); NameSpace tmp = new NameSpace(BeanShell.getNameSpace(), "transport"); tmp.setVariable("values", values); String clause = (String) BeanShell.eval(null, tmp, script); Cursor cursor = null; try { projection.insert(0, pk, null); cursor = contentResolver.query(uri, projection.getKeys().toArray(strings()), clause, null, null); if (cursor.moveToFirst()) { if (skipThis != null) { ValList rec = getRow(cursor); switch (skipThis.apply(projection, rec.toArray())) { case 2: // no case 3: // no all return 0; case 4: // cancel return null; } } else decision = -1; values.put(pk, cursor.getLong(0)); found = true; } } finally { projection.remove(0); if (cursor != null) cursor.close(); } } } return found; } private int decision = -1; public Function<Integer> skipThis(final View view, final Object[] items) { return new Function<Integer>() { public Integer apply(Object... params) { switch (decision) { case 1: return 0; case 3: return 2; default: BidiMultiMap projection = param(null, 0, params); DataModel model = new DataModel().setProjection(projection); model.addValues(false, (Object[])param(null, 1, params)); ValList row = vlist(); row.add(null); row.addAll(asList(items)); model.addValues(false, row.toArray()); JTable table = model.makeTable(); table.getSelectionModel().setSelectionInterval(1, 1); return decision = new AlertDialog(view, getProperty("dataview.prompt-update.message"), "", scrollableViewport(table, new Dimension(800,100)), 5, AlertDialog.behavior, null, null).open().getResult(); } } }; } public Object updateOrInsert(String uriString, ValMap profile, BidiMultiMap projection, Object primaryKeyColumnName, ContentValues values, Object...params) { Uri uri = makeUri(uriString); try { boolean primaryKey = notNullOrEmpty(primaryKeyColumnName); boolean primaryKeyExtraColumn = primaryKey && !projection.getKeys().contains(primaryKeyColumnName.toString()); if (primaryKeyExtraColumn) { boolean found; Object retval = updateOrInsert_query(uri, profile, projection, stringValueOf(primaryKeyColumnName), values, param((Function<Integer>)null, 0, params)); if (retval instanceof Boolean) found = (Boolean) retval; else if (retval instanceof Integer) return retval; else return null; primaryKeyExtraColumn = !found; } Object retval = null; if (primaryKeyExtraColumn) { values.putNull(primaryKeyColumnName.toString()); retval = contentResolver.insert(uri, values); } else if (primaryKey) { String pk = primaryKeyColumnName.toString(); Object pkval = values.get(pk); values.remove(pk); retval = contentResolver.update(uri, values, pk + "=?", strings(pkval.toString())); } else retval = contentResolver.insert(uri, values); return retval; } catch (Exception e) { BerichtsheftPlugin.consoleMessage("dataview.updateOrInsert.message.1", stringValueOf(uri), e.getMessage()); return null; } } public int[] pickRecords(View view, JTable table, String uriString, ValMap profile) { DataModel model = (DataModel) table.getModel(); BidiMultiMap projection = model.getProjection(); Object pk = info.get("PRIMARY_KEY"); int[] results = ints(0,0,0); for (int i = 0; i < model.getRowCount(); i++) { int row = table.convertRowIndexToView(i); if (table.isRowSelected(row)) { Object[] items = model.getValues(false, i); ContentValues values = contentValues(info, projection.getKeys(), items); Object result = updateOrInsert(uriString, profile, projection, pk, values, skipThis(view, items)); if (!checkResult(result, ++results[2])) { results = null; break; } else if (result instanceof Uri) results[0]++; else results[1] += (Integer) result; } } return results; } public boolean checkResult(Object result, int recno) { if (result != null) { if (result instanceof Uri) { long id = ContentUris.parseId((Uri) result); if (id < 0) BerichtsheftPlugin.consoleMessage("dataview.updateOrInsert.message.3", recno); } else if (result instanceof Integer) { if ((Integer)result < 1) BerichtsheftPlugin.consoleMessage("dataview.updateOrInsert.message.4", recno); } } else if (decision == 4) { BerichtsheftPlugin.consoleMessage("dataview.updateOrInsert.message.2", recno); return false; } return true; } public Uri insert(String uriString, ContentValues values) { Uri uri = makeUri(uriString); return contentResolver.insert(uri, values); } public int update(String uriString, ContentValues values, Object...params) { Uri uri = makeUri(uriString); String where = param(null, 0, params); String[] whereArgs = param(null, 1, params); return contentResolver.update(uri, values, where, whereArgs); } public int delete(String uriString, Object...params) { Uri uri = makeUri(uriString); String where = param(null, 0, params); String[] whereArgs = param(null, 1, params); return contentResolver.delete(uri, where, whereArgs); } }