package de.geeksfactory.opacclient.searchfields; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Set; import de.geeksfactory.opacclient.objects.Library; import de.geeksfactory.opacclient.searchfields.SearchField.Meaning; import de.geeksfactory.opacclient.utils.JsonKeyIterator; public class MeaningDetectorImpl implements MeaningDetector { private static final String DIR = "meanings"; private Map<String, String> meanings; private ClassLoader classLoader; public MeaningDetectorImpl(Library lib) { meanings = new HashMap<>(); classLoader = getClass().getClassLoader(); if (lib != null) { InputStream file; if ((file = getFile("general.json")) != null) // General { loadFile(file); } if ((file = getFile(lib.getApi() + ".json")) != null) // Api specific { loadFile(file); } if ((file = getFile(lib.getIdent() + ".json")) != null) // Library specific { loadFile(file); } } } private InputStream getFile(String s) { return classLoader.getResourceAsStream(DIR + "/" + s); } private static String readFile(InputStream is) throws IOException { BufferedReader reader = new BufferedReader(new InputStreamReader(is, "utf-8")); String line; StringBuilder builder = new StringBuilder(); while ((line = reader.readLine()) != null) { builder.append(line); } is.close(); return builder.toString(); } private void loadFile(InputStream is) { try { String jsonStr = readFile(is); JSONObject json = new JSONObject(jsonStr); // Detect layout of the JSON entries. Can be "field name": // "meaning" or "meaning": [ "field name", "field name", ... ] Iterator<String> iter = new JsonKeyIterator(json); if (!iter.hasNext()) { return; // No entries } String firstKey = iter.next(); Object firstValue = json.get(firstKey); boolean arrayLayout = firstValue instanceof JSONArray; if (arrayLayout) { for (int i = 0; i < ((JSONArray) firstValue).length(); i++) { meanings.put(((JSONArray) firstValue).getString(i), firstKey); } while (iter.hasNext()) { String key = iter.next(); JSONArray val = json.getJSONArray(key); for (int i = 0; i < val.length(); i++) { meanings.put(val.getString(i), key); } } } else { meanings.put(firstKey, (String) firstValue); while (iter.hasNext()) { String key = iter.next(); String val = json.getString(key); meanings.put(key, val); } } } catch (JSONException | IOException e) { e.printStackTrace(); } } @Override public SearchField detectMeaning(SearchField field) { if (field.getData() != null && field.getData().has("meaning")) { try { String meaningData = field.getData().getString("meaning"); String meaningName = meanings.get(meaningData); if (meaningName != null) { return processMeaning(field, meaningName); } } catch (JSONException e) { e.printStackTrace(); } } else { String meaningName = meanings.get(field.getDisplayName()); if (meaningName != null) { return processMeaning(field, meaningName); } } field.setAdvanced(true); return field; } /** * Adds a meaning to this MeaningDetector. This will not be persisted. * * @param name the name of the field * @param meaning the meaning to assign */ public void addMeaning(String name, Meaning meaning) { meanings.put(name, meaning.toString()); } private SearchField processMeaning(SearchField field, String meaningName) { Meaning meaning = Meaning.valueOf(meaningName); SearchField oldfield = field; if (field instanceof TextSearchField && meaning == Meaning.FREE) { ((TextSearchField) field).setFreeSearch(true); ((TextSearchField) field).setHint(field.getDisplayName()); } else if (field instanceof TextSearchField && (meaning == Meaning.BARCODE || meaning == Meaning.ISBN)) { field = new BarcodeSearchField(field.getId(), field.getDisplayName(), field.isAdvanced(), ((TextSearchField) field).isHalfWidth(), ((TextSearchField) field).getHint()); } else if (meaning == Meaning.AUDIENCE || meaning == Meaning.SYSTEM || meaning == Meaning.KEYWORD || meaning == Meaning.PUBLISHER) { field.setAdvanced(true); } field.setData(oldfield.getData()); field.setMeaning(meaning); return field; } public Set<String> getIgnoredFields() throws IOException, JSONException { JSONArray json = new JSONArray(readFile(getFile("ignore.json"))); Set<String> ignored = new HashSet<>(); for (int i = 0; i < json.length(); i++) { ignored.add(json.getString(i)); } return ignored; } }