Java tutorial
/* * Copyright 2012 Sauce Labs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.sebuilder.interpreter; import java.io.IOException; import java.io.Reader; import java.util.HashMap; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import org.json.JSONTokener; /** * Utilities for reading scripts. * @author zarkonnen */ public class IO { /** * @param r A Reader pointing to a JSON stream describing a script. * @return A script, ready to run. * @throws IOException If anything goes wrong with interpreting the JSON, or with the Reader. * @throws JSONException If the JSON can't be parsed. */ public static Script read(Reader r) throws IOException, JSONException { return parse(new JSONObject(new JSONTokener(r))); } /** * @param scriptO A JSONObject describing a script. * @return A script, ready to run. * @throws IOException If anything goes wrong with interpreting the JSON. */ public static Script parse(JSONObject scriptO) throws IOException { try { if (!scriptO.get("seleniumVersion").equals("2")) { throw new IOException("Unsupported Selenium version: \"" + scriptO.get("seleniumVersion") + "\"."); } if (scriptO.getInt("formatVersion") != 1) { throw new IOException( "Unsupported Selenium script format version: \"" + scriptO.get("formatVersion") + "\"."); } Script script = new Script(); JSONArray stepsA = scriptO.getJSONArray("steps"); for (int i = 0; i < stepsA.length(); i++) { JSONObject stepO = stepsA.getJSONObject(i); Script.Step step = new Script.Step(getStepTypeOfName(stepO.getString("type"))); step.negated = stepO.optBoolean("negated", false); script.steps.add(step); JSONArray keysA = stepO.names(); for (int j = 0; j < keysA.length(); j++) { String key = keysA.getString(j); if (key.equals("type") || key.equals("negated")) { continue; } if (stepO.optJSONObject(key) != null) { step.locatorParams.put(key, new Locator(stepO.getJSONObject(key).getString("type"), stepO.getJSONObject(key).getString("value"))); } else { step.stringParams.put(key, stepO.getString(key)); } } } return script; } catch (Exception e) { throw new IOException("Could not parse script.", e); } } /** * Mapping of the names of step types to their implementing classes, lazily loaded through * reflection. StepType classes must be in the com.sebuilder.interpreter.steptype package and * their name must be the capitalized name of their type. For example, the class for "get" is at * com.sebuilder.interpreter.steptype.Get. * * Assert/Verify/WaitFor/Store steps use "Getter" objects that encapsulate how to get the value * they are about. Getters should be named eg "Title" for "verifyTitle" and also be in the * com.sebuilder.interpreter.steptype package. */ private static final HashMap<String, StepType> typesMap = new HashMap<String, StepType>(); public static StepType getStepTypeOfName(String name) { try { if (!typesMap.containsKey(name)) { String className = name.substring(0, 1).toUpperCase() + name.substring(1); boolean rawStepType = true; if (name.startsWith("assert")) { className = className.substring("assert".length()); rawStepType = false; } if (name.startsWith("verify")) { className = className.substring("verify".length()); rawStepType = false; } if (name.startsWith("waitFor")) { className = className.substring("waitFor".length()); rawStepType = false; } if (name.startsWith("store") && !name.equals("store")) { className = className.substring("store".length()); rawStepType = false; } try { Class c = Class.forName("com.sebuilder.interpreter.steptype." + className); try { Object o = c.newInstance(); if (name.startsWith("assert")) { typesMap.put(name, new Assert((Getter) o)); } else if (name.startsWith("verify")) { typesMap.put(name, new Verify((Getter) o)); } else if (name.startsWith("waitFor")) { typesMap.put(name, new WaitFor((Getter) o)); } else if (name.startsWith("store") && !name.equals("store")) { typesMap.put(name, new Store((Getter) o)); } else { typesMap.put(name, (StepType) o); } } catch (InstantiationException ie) { throw new RuntimeException(c.getName() + " could not be instantiated.", ie); } catch (IllegalAccessException iae) { throw new RuntimeException(c.getName() + " could not be instantiated.", iae); } catch (ClassCastException cce) { throw new RuntimeException( c.getName() + " does not extend " + (rawStepType ? "StepType" : "Getter") + ".", cce); } } catch (ClassNotFoundException cnfe) { throw new RuntimeException( "No implementation class for step type \"" + name + "\" could be found.", cnfe); } } return typesMap.get(name); } catch (Exception e) { throw new RuntimeException("Step type \"" + name + "\" is not implemented.", e); } } }