Home | History | Annotate | Download | only in interpreter
      1 /*
      2  * Copyright (C) 2016 Google Inc.
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
      5  * use this file except in compliance with the License. You may obtain a copy of
      6  * the License at
      7  *
      8  * http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
     12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
     13  * License for the specific language governing permissions and limitations under
     14  * the License.
     15  */
     16 
     17 package com.googlecode.android_scripting.interpreter;
     18 
     19 import android.content.ContentProvider;
     20 import android.content.ContentValues;
     21 import android.content.Context;
     22 import android.content.SharedPreferences;
     23 import android.content.UriMatcher;
     24 import android.database.Cursor;
     25 import android.database.MatrixCursor;
     26 import android.net.Uri;
     27 import android.preference.PreferenceManager;
     28 
     29 import java.util.HashMap;
     30 import java.util.LinkedHashMap;
     31 import java.util.Map;
     32 
     33 /**
     34  * A provider that can be queried to obtain execution-related interpreter info.
     35  *
     36  * <p>
     37  * To create an interpreter APK, please extend this content provider and implement getDescriptor()
     38  * and getEnvironmentSettings().<br>
     39  * Please declare the provider in the android manifest xml (the authority values has to be set to
     40  * your_package_name.provider_name).
     41  *
     42  * @author Alexey Reznichenko (alexey.reznichenko (at) gmail.com)
     43  */
     44 public abstract class InterpreterProvider extends ContentProvider {
     45 
     46   private static final int PROPERTIES = 1;
     47   private static final int ENVIRONMENT_VARIABLES = 2;
     48   private static final int ARGUMENTS = 3;
     49 
     50   private UriMatcher mUriMatcher;
     51   private SharedPreferences mPreferences;
     52 
     53   private InterpreterDescriptor mDescriptor;
     54   private Context mContext;
     55 
     56   public static final String MIME = "vnd.android.cursor.item/vnd.googlecode.interpreter";
     57 
     58   public InterpreterProvider() {
     59     mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
     60     String auth = this.getClass().getName().toLowerCase();
     61     mUriMatcher.addURI(auth, InterpreterConstants.PROVIDER_PROPERTIES, PROPERTIES);
     62     mUriMatcher.addURI(auth, InterpreterConstants.PROVIDER_ENVIRONMENT_VARIABLES,
     63         ENVIRONMENT_VARIABLES);
     64     mUriMatcher.addURI(auth, InterpreterConstants.PROVIDER_ARGUMENTS, ARGUMENTS);
     65   }
     66 
     67   /**
     68    * Returns an instance of the class that implements the desired {@link InterpreterDescriptor}.
     69    */
     70   protected abstract InterpreterDescriptor getDescriptor();
     71 
     72   @Override
     73   public int delete(Uri uri, String selection, String[] selectionArgs) {
     74     return 0;
     75   }
     76 
     77   @Override
     78   public String getType(Uri uri) {
     79     return MIME;
     80   }
     81 
     82   @Override
     83   public Uri insert(Uri uri, ContentValues values) {
     84     return null;
     85   }
     86 
     87   @Override
     88   public boolean onCreate() {
     89     mDescriptor = getDescriptor();
     90     mContext = getContext();
     91     mPreferences = PreferenceManager.getDefaultSharedPreferences(mContext);
     92     return false;
     93   }
     94 
     95   @Override
     96   public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
     97       String sortOrder) {
     98     if (!isInterpreterInstalled()) {
     99       return null;
    100     }
    101     Map<String, String> map;
    102     switch (mUriMatcher.match(uri)) {
    103     case PROPERTIES:
    104       map = getProperties();
    105       break;
    106     case ENVIRONMENT_VARIABLES:
    107       map = getEnvironmentVariables();
    108       break;
    109     case ARGUMENTS:
    110       map = getArguments();
    111       break;
    112     default:
    113       map = null;
    114     }
    115     return buildCursorFromMap(map);
    116   }
    117 
    118   @Override
    119   public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
    120     return 0;
    121   }
    122 
    123   private boolean isInterpreterInstalled() {
    124     return mPreferences.getBoolean(InterpreterConstants.INSTALLED_PREFERENCE_KEY, false);
    125   }
    126 
    127   private Cursor buildCursorFromMap(Map<String, String> map) {
    128     if (map == null) {
    129       return null;
    130     }
    131     MatrixCursor cursor = new MatrixCursor(map.keySet().toArray(new String[map.size()]));
    132     cursor.addRow(map.values());
    133     return cursor;
    134   }
    135 
    136   private Map<String, String> getProperties() {
    137     Map<String, String> values = new HashMap<String, String>();
    138     values.put(InterpreterPropertyNames.NAME, mDescriptor.getName());
    139     values.put(InterpreterPropertyNames.NICE_NAME, mDescriptor.getNiceName());
    140     values.put(InterpreterPropertyNames.EXTENSION, mDescriptor.getExtension());
    141     values.put(InterpreterPropertyNames.BINARY, mDescriptor.getBinary(mContext).getAbsolutePath());
    142     values.put(InterpreterPropertyNames.INTERACTIVE_COMMAND, mDescriptor
    143         .getInteractiveCommand(mContext));
    144     values.put(InterpreterPropertyNames.SCRIPT_COMMAND, mDescriptor.getScriptCommand(mContext));
    145     values.put(InterpreterPropertyNames.HAS_INTERACTIVE_MODE, Boolean.toString(mDescriptor
    146         .hasInteractiveMode()));
    147     return values;
    148   }
    149 
    150   private Map<String, String> getEnvironmentVariables() {
    151     Map<String, String> values = new HashMap<String, String>();
    152     values.putAll(mDescriptor.getEnvironmentVariables(mContext));
    153     return values;
    154   }
    155 
    156   private Map<String, String> getArguments() {
    157     Map<String, String> values = new LinkedHashMap<String, String>();
    158     int column = 0;
    159     for (String argument : mDescriptor.getArguments(mContext)) {
    160       values.put(Integer.toString(column), argument);
    161       column++;
    162     }
    163     return values;
    164   }
    165 }
    166