Java tutorial
/* * Copyright (C) 2012-2016 Tobias Brunner * Copyright (C) 2012 Giuliano Grassi * Copyright (C) 2012 Ralf Sager * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. */ package org.strongswan.android.data; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.SQLException; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.database.sqlite.SQLiteQueryBuilder; import android.util.Log; import org.apache.commons.lang3.StringUtils; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; import java.util.List; public class VpnProfileDataSource { private static final String TAG = VpnProfileDataSource.class.getSimpleName(); public static final String KEY_ID = "_id"; public static final String KEY_NAME = "name"; public static final String KEY_GATEWAY = "gateway"; public static final String KEY_VPN_TYPE = "vpn_type"; public static final String KEY_USERNAME = "username"; public static final String KEY_PASSWORD = "password"; public static final String KEY_CERTIFICATE = "certificate"; public static final String KEY_USER_CERTIFICATE = "user_certificate"; public static final String KEY_MTU = "mtu"; public static final String KEY_PORT = "port"; public static final String KEY_SPLIT_TUNNELING = "split_tunneling"; public static final String KEY_LOCAL_ID = "local_id"; public static final String KEY_REMOTE_ID = "remote_id"; //fancyfon public static final String KEY_CERTIFICATE_ID = "id_certificate"; public static final String KEY_ALLOWED_APPLICATIONS = "allowed_applications"; private static final String EMPTY_STRING = ""; private static final String SPLIT_TUNNELING_DEFAULT_VALUE = "0"; private DatabaseHelper mDbHelper; private SQLiteDatabase mDatabase; private final Context mContext; private static final String DATABASE_NAME = "strongswan.db"; private static final String TABLE_VPNPROFILE = "vpnprofile"; public static final String KEY_LOGGING_LEVEL = "logging_level"; private static final int DATABASE_VERSION = 10; public static final String DATABASE_CREATE = "CREATE TABLE " + TABLE_VPNPROFILE + " (" + KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + KEY_NAME + " TEXT NOT NULL," + KEY_GATEWAY + " TEXT NOT NULL," + KEY_VPN_TYPE + " TEXT NOT NULL," + KEY_USERNAME + " TEXT," + KEY_PASSWORD + " TEXT," + KEY_CERTIFICATE + " TEXT," + KEY_USER_CERTIFICATE + " TEXT," + KEY_MTU + " INTEGER," + KEY_PORT + " INTEGER," + KEY_SPLIT_TUNNELING + " INTEGER," + KEY_LOCAL_ID + " TEXT," + KEY_REMOTE_ID + " TEXT," + //fancyfon KEY_CERTIFICATE_ID + " TEXT," + KEY_ALLOWED_APPLICATIONS + " TEXT," + KEY_LOGGING_LEVEL + " INTEGER" + ");"; private static final String[] ALL_COLUMNS = new String[] { KEY_ID, KEY_NAME, KEY_GATEWAY, KEY_VPN_TYPE, KEY_USERNAME, KEY_PASSWORD, KEY_CERTIFICATE, KEY_USER_CERTIFICATE, KEY_MTU, KEY_PORT, KEY_SPLIT_TUNNELING, KEY_LOCAL_ID, KEY_REMOTE_ID, //fancyfon KEY_CERTIFICATE_ID, KEY_ALLOWED_APPLICATIONS, KEY_LOGGING_LEVEL }; private static class DatabaseHelper extends SQLiteOpenHelper { public DatabaseHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } @Override public void onCreate(SQLiteDatabase database) { database.execSQL(DATABASE_CREATE); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { Log.w(TAG, "Upgrading database from version " + oldVersion + " to " + newVersion); if (oldVersion < 2) { db.execSQL("ALTER TABLE " + TABLE_VPNPROFILE + " ADD " + KEY_USER_CERTIFICATE + " TEXT;"); } if (oldVersion < 3) { db.execSQL("ALTER TABLE " + TABLE_VPNPROFILE + " ADD " + KEY_VPN_TYPE + " TEXT DEFAULT '';"); } if (oldVersion < 4) { /* remove NOT NULL constraint from username column */ updateColumns(db); } if (oldVersion < 5) { fancyfonDatabaseUpdateVersion5(db); db.execSQL("ALTER TABLE " + TABLE_VPNPROFILE + " ADD " + KEY_MTU + " INTEGER;"); } if (oldVersion < 6) { fancyfonDatabaseUpdateVersion6(db); db.execSQL("ALTER TABLE " + TABLE_VPNPROFILE + " ADD " + KEY_PORT + " INTEGER;"); } if (oldVersion < 7) { db.execSQL("ALTER TABLE " + TABLE_VPNPROFILE + " ADD " + KEY_SPLIT_TUNNELING + " INTEGER;"); } if (oldVersion < 8) { db.execSQL("ALTER TABLE " + TABLE_VPNPROFILE + " ADD " + KEY_LOCAL_ID + " TEXT;"); db.execSQL("ALTER TABLE " + TABLE_VPNPROFILE + " ADD " + KEY_REMOTE_ID + " TEXT;"); } if (oldVersion < 10) { fancyfonDatabaseUpdateVersion10(db); } } private void fancyfonDatabaseUpdateVersion5(SQLiteDatabase db) { db.execSQL("ALTER TABLE " + TABLE_VPNPROFILE + " ADD " + KEY_ALLOWED_APPLICATIONS + " TEXT;"); } private void fancyfonDatabaseUpdateVersion6(SQLiteDatabase db) { db.execSQL("ALTER TABLE " + TABLE_VPNPROFILE + " ADD " + KEY_CERTIFICATE_ID + " TEXT;"); } private void fancyfonDatabaseUpdateVersion10(SQLiteDatabase db) { db.execSQL("ALTER TABLE " + TABLE_VPNPROFILE + " ADD " + KEY_LOGGING_LEVEL + " INTEGER DEFAULT 1;"); } private void updateColumns(SQLiteDatabase db) { db.beginTransaction(); try { db.execSQL("ALTER TABLE " + TABLE_VPNPROFILE + " RENAME TO tmp_" + TABLE_VPNPROFILE + ";"); db.execSQL(DATABASE_CREATE); StringBuilder insert = new StringBuilder("INSERT INTO " + TABLE_VPNPROFILE + " SELECT "); SQLiteQueryBuilder.appendColumns(insert, ALL_COLUMNS); db.execSQL(insert.append(" FROM tmp_" + TABLE_VPNPROFILE + ";").toString()); db.execSQL("DROP TABLE tmp_" + TABLE_VPNPROFILE + ";"); db.setTransactionSuccessful(); } finally { db.endTransaction(); } } } /** * Construct a new VPN profile data source. The context is used to * open/create the database. * @param context context used to access the database */ public VpnProfileDataSource(Context context) { this.mContext = context; } /** * Open the VPN profile data source. The database is automatically created * if it does not yet exist. If that fails an exception is thrown. * @return itself (allows to chain initialization calls) * @throws SQLException if the database could not be opened or created */ public VpnProfileDataSource open() throws SQLException { if (mDbHelper == null) { mDbHelper = new DatabaseHelper(mContext); mDatabase = mDbHelper.getWritableDatabase(); } return this; } /** * Close the data source. */ public void close() { if (mDbHelper != null) { mDbHelper.close(); mDbHelper = null; } } /** * Insert the given VPN profile into the database. On success the Id of * the object is updated and the object returned. * * @param profile the profile to add * @return the added VPN profile or null, if failed */ public VpnProfile insertProfile(VpnProfile profile) { ContentValues values = ContentValuesFromVpnProfile(profile); long insertId = mDatabase.insert(TABLE_VPNPROFILE, null, values); if (insertId == -1) { return null; } profile.setId(insertId); return profile; } /** * Updates the given VPN profile in the database. * @param profile the profile to update * @return true if update succeeded, false otherwise */ public boolean updateVpnProfile(VpnProfile profile) { long id = profile.getId(); ContentValues values = ContentValuesFromVpnProfile(profile); return mDatabase.update(TABLE_VPNPROFILE, values, KEY_ID + " = " + id, null) > 0; } /** * Delete the given VPN profile from the database. * @param profile the profile to delete * @return true if deleted, false otherwise */ public boolean deleteVpnProfile(VpnProfile profile) { if (profile == null) { return true; } String name = profile.getName(); return mDatabase.delete(TABLE_VPNPROFILE, KEY_NAME + " = \"" + name + "\"", null) > 0; } /** * Get a single VPN profile from the database. * @param name name of vpn profile * @return the profile or null, if not found */ public VpnProfile getVpnProfile(String name) { VpnProfile profile = null; Cursor cursor = null; try { cursor = mDatabase.query(TABLE_VPNPROFILE, ALL_COLUMNS, KEY_NAME + "=\"" + name + "\"", null, null, null, null); if (cursor.moveToFirst()) { profile = VpnProfileFromCursor(cursor); } } finally { closeCursor(cursor); } return profile; } /** * Get a single VPN profile from the database. * @param id the ID of the VPN profile * @return the profile or null, if not found */ public VpnProfile getVpnProfile(long id) { VpnProfile profile = null; Cursor cursor = null; try { cursor = mDatabase.query(TABLE_VPNPROFILE, ALL_COLUMNS, KEY_ID + "=" + id, null, null, null, null); if (cursor.moveToFirst()) { profile = VpnProfileFromCursor(cursor); } } finally { closeCursor(cursor); } return profile; } /** * Get a list of all VPN profiles stored in the database. * @return list of VPN profiles */ public List<VpnProfile> getAllVpnProfiles() { List<VpnProfile> vpnProfiles = new ArrayList<VpnProfile>(); Cursor cursor = null; try { cursor = mDatabase.query(TABLE_VPNPROFILE, ALL_COLUMNS, null, null, null, null, null); cursor.moveToFirst(); while (!cursor.isAfterLast()) { VpnProfile vpnProfile = VpnProfileFromCursor(cursor); vpnProfiles.add(vpnProfile); cursor.moveToNext(); } } finally { closeCursor(cursor); } return vpnProfiles; } private VpnProfile VpnProfileFromCursor(Cursor cursor) { VpnProfile profile = new VpnProfile(); profile.setId(cursor.getLong(cursor.getColumnIndex(KEY_ID))); profile.setName(cursor.getString(cursor.getColumnIndex(KEY_NAME))); profile.setGateway(cursor.getString(cursor.getColumnIndex(KEY_GATEWAY))); profile.setVpnType(VpnType.fromIdentifier(cursor.getString(cursor.getColumnIndex(KEY_VPN_TYPE)))); profile.setUsername(cursor.getString(cursor.getColumnIndex(KEY_USERNAME))); String password = cursor.getString(cursor.getColumnIndex(KEY_PASSWORD)); if (StringUtils.isNotEmpty(password)) { profile.setPassword(password); } profile.setCertificateAlias(cursor.getString(cursor.getColumnIndex(KEY_CERTIFICATE))); profile.setUserCertificateAlias(cursor.getString(cursor.getColumnIndex(KEY_USER_CERTIFICATE))); profile.setMTU(getInt(cursor, cursor.getColumnIndex(KEY_MTU))); profile.setPort(getInt(cursor, cursor.getColumnIndex(KEY_PORT))); profile.setSplitTunneling(getInt(cursor, cursor.getColumnIndex(KEY_SPLIT_TUNNELING))); profile.setLocalId(cursor.getString(cursor.getColumnIndex(KEY_LOCAL_ID))); profile.setRemoteId(cursor.getString(cursor.getColumnIndex(KEY_REMOTE_ID))); profile = setFancyFonValuesOnProfileFromCursor(profile, cursor); return profile; } private VpnProfile setFancyFonValuesOnProfileFromCursor(VpnProfile profile, Cursor cursor) { profile.setCertificateId(cursor.getString(cursor.getColumnIndex(KEY_CERTIFICATE_ID))); profile.setAllowedApplications( convertFromString(cursor.getString(cursor.getColumnIndex(KEY_ALLOWED_APPLICATIONS)))); profile.setLoggingLevel(cursor.getInt(cursor.getColumnIndex(KEY_LOGGING_LEVEL))); return profile; } private ContentValues ContentValuesFromVpnProfile(VpnProfile profile) { ContentValues values = new ContentValues(); values.put(KEY_NAME, profile.getName()); values.put(KEY_GATEWAY, profile.getGateway()); values.put(KEY_VPN_TYPE, profile.getVpnType().getIdentifier()); values.put(KEY_USERNAME, profile.getUsername()); values.put(KEY_PASSWORD, profile.getPassword()); values.put(KEY_CERTIFICATE, profile.getCertificateAlias()); values.put(KEY_USER_CERTIFICATE, profile.getUserCertificateAlias()); //not implemented in ff values.put(KEY_MTU, EMPTY_STRING); values.put(KEY_PORT, EMPTY_STRING); values.put(KEY_SPLIT_TUNNELING, SPLIT_TUNNELING_DEFAULT_VALUE); values.put(KEY_LOCAL_ID, EMPTY_STRING); values.put(KEY_REMOTE_ID, EMPTY_STRING); values = putFancyFonValues(values, profile); return values; } private ContentValues putFancyFonValues(ContentValues values, VpnProfile profile) { values.put(KEY_CERTIFICATE_ID, profile.getCertificateId()); values.put(KEY_ALLOWED_APPLICATIONS, convertToString(profile.getAllowedApplications())); if (profile.getLoggingLevel() == 0) { profile.setLoggingLevel(1); } values.put(KEY_LOGGING_LEVEL, profile.getLoggingLevel()); return values; } private String convertToString(ArrayList<String> list) { if (list == null) { return EMPTY_STRING; } StringBuilder buffer = new StringBuilder(list.size() * 16); Iterator<String> it = list.iterator(); while (it.hasNext()) { Object next = it.next(); buffer.append(next); if (it.hasNext()) { buffer.append(","); } } return buffer.toString(); } private ArrayList<String> convertFromString(String string) { if (string == null || string.length() == 0) { return new ArrayList<String>(); } return new ArrayList<String>(Arrays.asList(string.split(","))); } private void closeCursor(Cursor cursor) { if (cursor != null) { cursor.close(); } } private Integer getInt(Cursor cursor, int columnIndex) { return cursor.isNull(columnIndex) ? null : cursor.getInt(columnIndex); } }