/* * Geopaparazzi - Digital field mapping on Android based devices * Copyright (C) 2010 HydroloGIS (www.hydrologis.com) * * 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 3 of the License, or * (at your option) any later version. * * 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. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package eu.geopaparazzi.library.forms; import static eu.geopaparazzi.library.forms.FormUtilities.ATTR_FORMNAME; import static eu.geopaparazzi.library.forms.FormUtilities.ATTR_FORMS; import static eu.geopaparazzi.library.forms.FormUtilities.ATTR_SECTIONNAME; import static eu.geopaparazzi.library.forms.FormUtilities.TAG_FORMITEMS; import static eu.geopaparazzi.library.forms.FormUtilities.TAG_FORMS; import static eu.geopaparazzi.library.forms.FormUtilities.TAG_ITEM; import static eu.geopaparazzi.library.forms.FormUtilities.TAG_ITEMS; import static eu.geopaparazzi.library.forms.FormUtilities.TAG_LONGNAME; import static eu.geopaparazzi.library.forms.FormUtilities.TAG_SHORTNAME; import static eu.geopaparazzi.library.forms.FormUtilities.TAG_VALUES; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Set; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import android.content.Context; import android.content.res.AssetManager; import eu.geopaparazzi.library.util.FileUtilities; import eu.geopaparazzi.library.util.ResourcesManager; import eu.geopaparazzi.library.util.debug.Debug; /** * Singleton that takes care of tags. * * <p>The tags are looked for in the following places:</p> * <ul> * <li>a file named <b>tags.json</b> inside the application folder (Which * is retrieved via {@link ResourcesManager#getApplicationDir()}</li> * <li>or, if the above is missing, a file named <b>tags/tags.json</b> in * the asset folder of the project. In that case the file is copied over * to the file in the first point.</li> * </ul> * * <p> * The tags file is subdivided as follows: * * [{ * "sectionname": "scheda_sisma", * "sectiondescription": "this produces a button names scheda_sisma", * "forms": [ * { * "formname": "Name of the section, used in the fragments list", * "formitems": [ * .... * .... * ] * },{ * "formname": "This name produces a second fragment", * "formitems": [ * .... * .... * ] * } * ] * },{ * "sectionname": "section 2", * "sectiondescription": "this produces a second button", * "forms": [ * { * "formname": "this produces one fragment in the list", * "formitems": [ * .... * .... * ] * },{ * * } * ] * }] * * * * @author Andrea Antonello (www.hydrologis.com) */ @SuppressWarnings("nls") public class TagsManager { public static String TAGSFILENAME = "tags.json"; private LinkedHashMap<String, JSONObject> sectionsMap = null; private static TagsManager tagsManager; /** * Gets the manager singleton. * * @return the {@link TagsManager} singleton. * @throws IOException */ public static synchronized TagsManager getInstance( Context context ) throws Exception { if (tagsManager == null) { tagsManager = new TagsManager(); tagsManager.getFileTags(context); } return tagsManager; } /** * Performs the first data reading. Necessary for everything else. * * @param context * @throws Exception */ private void getFileTags( Context context ) throws Exception { if (sectionsMap == null) { sectionsMap = new LinkedHashMap<String, JSONObject>(); } File applicationDir = ResourcesManager.getInstance(context).getApplicationDir(); File tagsFile = new File(applicationDir, TAGSFILENAME); if (!tagsFile.exists() || Debug.doOverwriteTags) { AssetManager assetManager = context.getAssets(); InputStream inputStream = assetManager.open("tags/tags.json"); FileUtilities.copyFile(inputStream, new FileOutputStream(tagsFile)); } if (tagsFile.exists()) { sectionsMap.clear(); String tagsFileString = FileUtilities.readfile(tagsFile); JSONArray sectionsArrayObj = new JSONArray(tagsFileString); int tagsNum = sectionsArrayObj.length(); for( int i = 0; i < tagsNum; i++ ) { JSONObject jsonObject = sectionsArrayObj.getJSONObject(i); if (jsonObject.has(ATTR_SECTIONNAME)) { String sectionName = jsonObject.get(ATTR_SECTIONNAME).toString(); sectionsMap.put(sectionName, jsonObject); } } } } public Set<String> getSectionNames() { return sectionsMap.keySet(); } public JSONObject getSectionByName( String name ) { return sectionsMap.get(name); } public static List<String> getFormNames4Section( JSONObject section ) throws JSONException { List<String> names = new ArrayList<String>(); JSONArray jsonArray = section.getJSONArray(ATTR_FORMS); if (jsonArray != null && jsonArray.length() > 0) { for( int i = 0; i < jsonArray.length(); i++ ) { JSONObject jsonObject = jsonArray.getJSONObject(i); if (jsonObject.has(ATTR_FORMNAME)) { String formName = jsonObject.getString(ATTR_FORMNAME); names.add(formName); } } } return names; } public static JSONObject getForm4Name( String formName, JSONObject section ) throws JSONException { JSONArray jsonArray = section.getJSONArray(ATTR_FORMS); if (jsonArray != null && jsonArray.length() > 0) { for( int i = 0; i < jsonArray.length(); i++ ) { JSONObject jsonObject = jsonArray.getJSONObject(i); if (jsonObject.has(ATTR_FORMNAME)) { String tmpFormName = jsonObject.getString(ATTR_FORMNAME); if (tmpFormName.equals(formName)) { return jsonObject; } } } } return null; } public static TagObject stringToTagObject( String jsonString ) throws JSONException { JSONObject jsonObject = new JSONObject(jsonString); String shortname = jsonObject.getString(TAG_SHORTNAME); String longname = jsonObject.getString(TAG_LONGNAME); TagObject tag = new TagObject(); tag.shortName = shortname; tag.longName = longname; if (jsonObject.has(TAG_FORMS)) { tag.hasForm = true; } tag.jsonString = jsonString; return tag; } /** * Utility method to get the formitems of a form object. * * <p>Note that the entering json object has to be one * object of the main array, not THE main array itself, * i.e. a choice was already done. * * @param jsonObj the single object. * @return the array of items of the contained form or <code>null</code> if * no form is contained. * @throws JSONException */ public static JSONArray getFormItems( JSONObject formObj ) throws JSONException { if (formObj.has(TAG_FORMITEMS)) { JSONArray formItemsArray = formObj.getJSONArray(TAG_FORMITEMS); return formItemsArray; } return null; } /** * Utility method to get the combo items of a formitem object. * * @param formItem the json form <b>item</b>. * @return the array of items. * @throws JSONException */ public static JSONArray getComboItems( JSONObject formItem ) throws JSONException { if (formItem.has(TAG_VALUES)) { JSONObject valuesObj = formItem.getJSONObject(TAG_VALUES); if (valuesObj.has(TAG_ITEMS)) { JSONArray itemsArray = valuesObj.getJSONArray(TAG_ITEMS); return itemsArray; } } return null; } public static String[] comboItems2StringArray( JSONArray comboItems ) throws JSONException { int length = comboItems.length(); String[] itemsArray = new String[length]; for( int i = 0; i < length; i++ ) { JSONObject itemObj = comboItems.getJSONObject(i); if (itemObj.has(TAG_ITEM)) { itemsArray[i] = itemObj.getString(TAG_ITEM).trim(); } else { itemsArray[i] = " - "; } } return itemsArray; } public static class TagObject { public String shortName; public String longName; public boolean hasForm; public String jsonString; } }