1227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks/* 2227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Copyright (C) 2011 The Android Open Source Project 3227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 4227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Licensed under the Apache License, Version 2.0 (the "License"); 5227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * you may not use this file except in compliance with the License. 6227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * You may obtain a copy of the License at 7227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 8227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * http://www.apache.org/licenses/LICENSE-2.0 9227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 10227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Unless required by applicable law or agreed to in writing, software 11227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * distributed under the License is distributed on an "AS IS" BASIS, 12227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * See the License for the specific language governing permissions and 14227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * limitations under the License. 15227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 16227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 17227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendrickspackage androidx.media.filterfw; 18227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 19227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport android.text.TextUtils; 20227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 21227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport java.io.InputStream; 22227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport java.io.IOException; 23227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport java.io.StringReader; 24227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport java.util.ArrayList; 25227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 26227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport javax.xml.parsers.ParserConfigurationException; 27227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport javax.xml.parsers.SAXParser; 28227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport javax.xml.parsers.SAXParserFactory; 29227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 30227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport org.xml.sax.Attributes; 31227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport org.xml.sax.InputSource; 32227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport org.xml.sax.SAXException; 33227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport org.xml.sax.XMLReader; 34227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport org.xml.sax.helpers.DefaultHandler; 35227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 36227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks/** 37227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * A GraphReader allows obtaining filter graphs from XML graph files or strings. 38227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 39227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendrickspublic class GraphReader { 40227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 41227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private static interface Command { 42227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public void execute(CommandStack stack); 43227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 44227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 45227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private static class CommandStack { 46227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private ArrayList<Command> mCommands = new ArrayList<Command>(); 47227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private FilterGraph.Builder mBuilder; 48227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private FilterFactory mFactory; 49227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private MffContext mContext; 50227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 51227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public CommandStack(MffContext context) { 52227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mContext = context; 53227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mBuilder = new FilterGraph.Builder(mContext); 54227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mFactory = new FilterFactory(); 55227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 56227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 57227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public void execute() { 58227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks for (Command command : mCommands) { 59227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks command.execute(this); 60227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 61227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 62227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 63227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public void append(Command command) { 64227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mCommands.add(command); 65227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 66227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 67227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public FilterFactory getFactory() { 68227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return mFactory; 69227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 70227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 71227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public MffContext getContext() { 72227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return mContext; 73227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 74227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 75227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks protected FilterGraph.Builder getBuilder() { 76227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return mBuilder; 77227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 78227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 79227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 80227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private static class ImportPackageCommand implements Command { 81227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private String mPackageName; 82227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 83227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public ImportPackageCommand(String packageName) { 84227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mPackageName = packageName; 85227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 86227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 87227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks @Override 88227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public void execute(CommandStack stack) { 89227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks try { 90227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks stack.getFactory().addPackage(mPackageName); 91227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } catch (IllegalArgumentException e) { 92227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks throw new RuntimeException(e.getMessage()); 93227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 94227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 95227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 96227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 97227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private static class AddLibraryCommand implements Command { 98227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private String mLibraryName; 99227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 100227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public AddLibraryCommand(String libraryName) { 101227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mLibraryName = libraryName; 102227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 103227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 104227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks @Override 105227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public void execute(CommandStack stack) { 106227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks FilterFactory.addFilterLibrary(mLibraryName); 107227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 108227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 109227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 110227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private static class AllocateFilterCommand implements Command { 111227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private String mClassName; 112227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private String mFilterName; 113227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 114227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public AllocateFilterCommand(String className, String filterName) { 115227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mClassName = className; 116227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mFilterName = filterName; 117227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 118227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 119227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks @Override 1208a985d24ce9a38f40ed88fecbdcd0e75e3a68f44John Spurlock public void execute(CommandStack stack) { 121227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks Filter filter = null; 122227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks try { 123227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks filter = stack.getFactory().createFilterByClassName(mClassName, 124227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mFilterName, 125227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks stack.getContext()); 126227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } catch (IllegalArgumentException e) { 127227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks throw new RuntimeException("Error creating filter " + mFilterName + "!", e); 128227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 129227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks stack.getBuilder().addFilter(filter); 130227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 131227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 132227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 133227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private static class AddSourceSlotCommand implements Command { 134227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private String mName; 135227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private String mSlotName; 136227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 137227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public AddSourceSlotCommand(String name, String slotName) { 138227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mName = name; 139227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mSlotName = slotName; 140227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 141227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 142227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks @Override 143227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public void execute(CommandStack stack) { 144227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks stack.getBuilder().addFrameSlotSource(mName, mSlotName); 145227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 146227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 147227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 148227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private static class AddTargetSlotCommand implements Command { 149227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private String mName; 150227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private String mSlotName; 151227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 152227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public AddTargetSlotCommand(String name, String slotName) { 153227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mName = name; 154227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mSlotName = slotName; 155227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 156227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 157227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks @Override 158227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public void execute(CommandStack stack) { 159227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks stack.getBuilder().addFrameSlotTarget(mName, mSlotName); 160227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 161227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 162227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 163227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private static class AddVariableCommand implements Command { 164227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private String mName; 165227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private Object mValue; 166227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 167227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public AddVariableCommand(String name, Object value) { 168227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mName = name; 169227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mValue = value; 170227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 171227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 172227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks @Override 173227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public void execute(CommandStack stack) { 174227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks stack.getBuilder().addVariable(mName, mValue); 175227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 176227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 177227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 178227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private static class SetFilterInputCommand implements Command { 179227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private String mFilterName; 180227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private String mFilterInput; 181227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private Object mValue; 182227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 183227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public SetFilterInputCommand(String filterName, String input, Object value) { 184227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mFilterName = filterName; 185227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mFilterInput = input; 186227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mValue = value; 187227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 188227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 189227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks @Override 190227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public void execute(CommandStack stack) { 191227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (mValue instanceof Variable) { 192227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks String varName = ((Variable)mValue).name; 193227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks stack.getBuilder().assignVariableToFilterInput(varName, mFilterName, mFilterInput); 194227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } else { 195227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks stack.getBuilder().assignValueToFilterInput(mValue, mFilterName, mFilterInput); 196227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 197227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 198227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 199227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 200227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private static class ConnectCommand implements Command { 201227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private String mSourceFilter; 202227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private String mSourcePort; 203227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private String mTargetFilter; 204227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private String mTargetPort; 205227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 206227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public ConnectCommand(String sourceFilter, 207227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks String sourcePort, 208227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks String targetFilter, 209227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks String targetPort) { 210227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mSourceFilter = sourceFilter; 211227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mSourcePort = sourcePort; 212227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mTargetFilter = targetFilter; 213227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mTargetPort = targetPort; 214227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 215227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 216227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks @Override 217227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public void execute(CommandStack stack) { 218227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks stack.getBuilder().connect(mSourceFilter, mSourcePort, mTargetFilter, mTargetPort); 219227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 220227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 221227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 222227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private static class Variable { 223227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public String name; 224227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 225227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public Variable(String name) { 226227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks this.name = name; 227227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 228227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 229227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 230227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private static class XmlGraphReader { 231227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 232227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private SAXParserFactory mParserFactory; 233227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 234227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private static class GraphDataHandler extends DefaultHandler { 235227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 236227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private CommandStack mCommandStack; 237227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private boolean mInGraph = false; 238227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private String mCurFilterName = null; 239227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 240227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public GraphDataHandler(CommandStack commandStack) { 241227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mCommandStack = commandStack; 242227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 243227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 244227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks @Override 245227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public void startElement(String uri, String localName, String qName, Attributes attr) 246227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks throws SAXException { 247227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (localName.equals("graph")) { 248227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks beginGraph(); 249227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } else { 250227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks assertInGraph(localName); 251227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (localName.equals("import")) { 252227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks addImportCommand(attr); 253227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } else if (localName.equals("library")) { 254227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks addLibraryCommand(attr); 255227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } else if (localName.equals("connect")) { 256227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks addConnectCommand(attr); 257227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } else if (localName.equals("var")) { 258227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks addVarCommand(attr); 259227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } else if (localName.equals("filter")) { 260227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks beginFilter(attr); 261227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } else if (localName.equals("input")) { 262227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks addFilterInput(attr); 263227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } else { 264227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks throw new SAXException("Unknown XML element '" + localName + "'!"); 265227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 266227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 267227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 268227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 269227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks @Override 270227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public void endElement (String uri, String localName, String qName) { 271227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (localName.equals("graph")) { 272227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks endGraph(); 273227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } else if (localName.equals("filter")) { 274227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks endFilter(); 275227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 276227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 277227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 278227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private void addImportCommand(Attributes attributes) throws SAXException { 279227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks String packageName = getRequiredAttribute(attributes, "package"); 280227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mCommandStack.append(new ImportPackageCommand(packageName)); 281227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 282227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 283227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private void addLibraryCommand(Attributes attributes) throws SAXException { 284227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks String libraryName = getRequiredAttribute(attributes, "name"); 285227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mCommandStack.append(new AddLibraryCommand(libraryName)); 286227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 287227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 288227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private void addConnectCommand(Attributes attributes) { 289227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks String sourcePortName = null; 290227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks String sourceFilterName = null; 291227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks String targetPortName = null; 292227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks String targetFilterName = null; 293227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 294227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks // check for shorthand: <connect source="filter:port" target="filter:port"/> 295227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks String sourceTag = attributes.getValue("source"); 296227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (sourceTag != null) { 297227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks String[] sourceParts = sourceTag.split(":"); 298227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (sourceParts.length == 2) { 299227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks sourceFilterName = sourceParts[0]; 300227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks sourcePortName = sourceParts[1]; 301227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } else { 302227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks throw new RuntimeException( 303227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks "'source' tag needs to have format \"filter:port\"! " + 304227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks "Alternatively, you may use the form " + 305227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks "'sourceFilter=\"filter\" sourcePort=\"port\"'."); 306227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 307227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } else { 308227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks sourceFilterName = attributes.getValue("sourceFilter"); 309227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks sourcePortName = attributes.getValue("sourcePort"); 310227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 311227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 312227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks String targetTag = attributes.getValue("target"); 313227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (targetTag != null) { 314227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks String[] targetParts = targetTag.split(":"); 315227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (targetParts.length == 2) { 316227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks targetFilterName = targetParts[0]; 317227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks targetPortName = targetParts[1]; 318227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } else { 319227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks throw new RuntimeException( 320227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks "'target' tag needs to have format \"filter:port\"! " + 321227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks "Alternatively, you may use the form " + 322227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks "'targetFilter=\"filter\" targetPort=\"port\"'."); 323227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 324227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } else { 325227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks targetFilterName = attributes.getValue("targetFilter"); 326227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks targetPortName = attributes.getValue("targetPort"); 327227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 328227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 329227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks String sourceSlotName = attributes.getValue("sourceSlot"); 330227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks String targetSlotName = attributes.getValue("targetSlot"); 331227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (sourceSlotName != null) { 332227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks sourceFilterName = "sourceSlot_" + sourceSlotName; 333227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mCommandStack.append(new AddSourceSlotCommand(sourceFilterName, 334227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks sourceSlotName)); 335227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks sourcePortName = "frame"; 336227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 337227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (targetSlotName != null) { 338227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks targetFilterName = "targetSlot_" + targetSlotName; 339227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mCommandStack.append(new AddTargetSlotCommand(targetFilterName, 340227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks targetSlotName)); 341227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks targetPortName = "frame"; 342227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 343227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks assertValueNotNull("sourceFilter", sourceFilterName); 344227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks assertValueNotNull("sourcePort", sourcePortName); 345227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks assertValueNotNull("targetFilter", targetFilterName); 346227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks assertValueNotNull("targetPort", targetPortName); 347227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks // TODO: Should slot connections auto-branch? 348227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mCommandStack.append(new ConnectCommand(sourceFilterName, 349227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks sourcePortName, 350227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks targetFilterName, 351227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks targetPortName)); 352227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 353227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 354227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private void addVarCommand(Attributes attributes) throws SAXException { 355227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks String varName = getRequiredAttribute(attributes, "name"); 356227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks Object varValue = getAssignmentValue(attributes); 357227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mCommandStack.append(new AddVariableCommand(varName, varValue)); 358227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 359227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 360227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private void beginGraph() throws SAXException { 361227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (mInGraph) { 362227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks throw new SAXException("Found more than one graph element in XML!"); 363227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 364227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mInGraph = true; 365227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 366227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 367227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private void endGraph() { 368227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mInGraph = false; 369227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 370227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 371227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private void beginFilter(Attributes attributes) throws SAXException { 372227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks String className = getRequiredAttribute(attributes, "class"); 373227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mCurFilterName = getRequiredAttribute(attributes, "name"); 374227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mCommandStack.append(new AllocateFilterCommand(className, mCurFilterName)); 375227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 376227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 377227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private void endFilter() { 378227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mCurFilterName = null; 379227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 380227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 381227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private void addFilterInput(Attributes attributes) throws SAXException { 382227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks // Make sure we are in a filter element 383227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (mCurFilterName == null) { 384227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks throw new SAXException("Found 'input' element outside of 'filter' " 385227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks + "element!"); 386227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 387227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 388227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks // Get input name and value 389227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks String inputName = getRequiredAttribute(attributes, "name"); 390227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks Object inputValue = getAssignmentValue(attributes); 391227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (inputValue == null) { 392227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks throw new SAXException("No value specified for input '" + inputName + "' " 393227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks + "of filter '" + mCurFilterName + "'!"); 394227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 395227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 396227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks // Push commmand 397227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mCommandStack.append(new SetFilterInputCommand(mCurFilterName, 398227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks inputName, 399227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks inputValue)); 400227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 401227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 402227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private void assertInGraph(String localName) throws SAXException { 403227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (!mInGraph) { 404227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks throw new SAXException("Encountered '" + localName + "' element outside of " 405227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks + "'graph' element!"); 406227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 407227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 408227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 409227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private static Object getAssignmentValue(Attributes attributes) { 410227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks String strValue = null; 411227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if ((strValue = attributes.getValue("stringValue")) != null) { 412227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return strValue; 413227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } else if ((strValue = attributes.getValue("booleanValue")) != null) { 414227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return Boolean.parseBoolean(strValue); 415227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } else if ((strValue = attributes.getValue("intValue")) != null) { 416227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return Integer.parseInt(strValue); 417227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } else if ((strValue = attributes.getValue("floatValue")) != null) { 418227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return Float.parseFloat(strValue); 419227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } else if ((strValue = attributes.getValue("floatsValue")) != null) { 420227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks String[] floatStrings = TextUtils.split(strValue, ","); 421227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks float[] result = new float[floatStrings.length]; 422227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks for (int i = 0; i < floatStrings.length; ++i) { 423227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks result[i] = Float.parseFloat(floatStrings[i]); 424227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 425227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return result; 426227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } else if ((strValue = attributes.getValue("varValue")) != null) { 427227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return new Variable(strValue); 428227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } else { 429227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return null; 430227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 431227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 432227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 433227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private static String getRequiredAttribute(Attributes attributes, String name) 434227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks throws SAXException { 435227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks String result = attributes.getValue(name); 436227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (result == null) { 437227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks throw new SAXException("Required attribute '" + name + "' not found!"); 438227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 439227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return result; 440227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 441227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 442227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private static void assertValueNotNull(String valueName, Object value) { 443227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (value == null) { 444227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks throw new NullPointerException("Required value '" + value + "' not specified!"); 445227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 446227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 447227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 448227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 449227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 450227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public XmlGraphReader() { 451227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mParserFactory = SAXParserFactory.newInstance(); 452227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 453227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 454227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public void parseString(String graphString, CommandStack commandStack) throws IOException { 455227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks try { 456227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks XMLReader reader = getReaderForCommandStack(commandStack); 457227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks reader.parse(new InputSource(new StringReader(graphString))); 458227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } catch (SAXException e) { 459227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks throw new IOException("XML parse error during graph parsing!", e); 460227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 461227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 462227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 463227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public void parseInput(InputStream inputStream, CommandStack commandStack) 464227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks throws IOException { 465227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks try { 466227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks XMLReader reader = getReaderForCommandStack(commandStack); 467227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks reader.parse(new InputSource(inputStream)); 468227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } catch (SAXException e) { 469227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks throw new IOException("XML parse error during graph parsing!", e); 470227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 471227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 472227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 473227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private XMLReader getReaderForCommandStack(CommandStack commandStack) throws IOException { 474227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks try { 475227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks SAXParser parser = mParserFactory.newSAXParser(); 476227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks XMLReader reader = parser.getXMLReader(); 477227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks GraphDataHandler graphHandler = new GraphDataHandler(commandStack); 478227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks reader.setContentHandler(graphHandler); 479227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return reader; 480227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } catch (ParserConfigurationException e) { 481227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks throw new IOException("Error creating SAXParser for graph parsing!", e); 482227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } catch (SAXException e) { 483227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks throw new IOException("Error creating XMLReader for graph parsing!", e); 484227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 485227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 486227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 487227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 488227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 489227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Read an XML graph from a String. 490227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 491227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * This function automatically checks each filters' signatures and throws a Runtime Exception 492227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * if required ports are unconnected. Use the 3-parameter version to avoid this behavior. 493227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 494227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @param context the MffContext into which to load the graph. 495227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @param xmlSource the graph specified in XML. 496227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @return the FilterGraph instance for the XML source. 497227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @throws IOException if there was an error parsing the source. 498227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 499227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public static FilterGraph readXmlGraph(MffContext context, String xmlSource) 500227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks throws IOException { 501227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks FilterGraph.Builder builder = getBuilderForXmlString(context, xmlSource); 502227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return builder.build(); 503227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 504227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 505227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 506227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Read an XML sub-graph from a String. 507227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 508227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @param context the MffContext into which to load the graph. 509227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @param xmlSource the graph specified in XML. 510227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @param parentGraph the parent graph. 511227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @return the FilterGraph instance for the XML source. 512227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @throws IOException if there was an error parsing the source. 513227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 514227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public static FilterGraph readXmlSubGraph( 515227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks MffContext context, String xmlSource, FilterGraph parentGraph) 516227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks throws IOException { 517227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks FilterGraph.Builder builder = getBuilderForXmlString(context, xmlSource); 518227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return builder.buildSubGraph(parentGraph); 519227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 520227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 521227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 522227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Read an XML graph from a resource. 523227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 524227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * This function automatically checks each filters' signatures and throws a Runtime Exception 525227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * if required ports are unconnected. Use the 3-parameter version to avoid this behavior. 526227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 527227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @param context the MffContext into which to load the graph. 528227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @param resourceId the XML resource ID. 529227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @return the FilterGraph instance for the XML source. 530227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @throws IOException if there was an error reading or parsing the resource. 531227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 532227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public static FilterGraph readXmlGraphResource(MffContext context, int resourceId) 533227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks throws IOException { 534227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks FilterGraph.Builder builder = getBuilderForXmlResource(context, resourceId); 535227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return builder.build(); 536227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 537227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 538227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 539227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Read an XML graph from a resource. 540227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 541227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * This function automatically checks each filters' signatures and throws a Runtime Exception 542227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * if required ports are unconnected. Use the 3-parameter version to avoid this behavior. 543227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 544227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @param context the MffContext into which to load the graph. 545227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @param resourceId the XML resource ID. 546227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @return the FilterGraph instance for the XML source. 547227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @throws IOException if there was an error reading or parsing the resource. 548227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 549227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public static FilterGraph readXmlSubGraphResource( 550227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks MffContext context, int resourceId, FilterGraph parentGraph) 551227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks throws IOException { 552227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks FilterGraph.Builder builder = getBuilderForXmlResource(context, resourceId); 553227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return builder.buildSubGraph(parentGraph); 554227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 555227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 556227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private static FilterGraph.Builder getBuilderForXmlString(MffContext context, String source) 557227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks throws IOException { 558227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks XmlGraphReader reader = new XmlGraphReader(); 559227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks CommandStack commands = new CommandStack(context); 560227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks reader.parseString(source, commands); 561227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks commands.execute(); 562227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return commands.getBuilder(); 563227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 564227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 565227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private static FilterGraph.Builder getBuilderForXmlResource(MffContext context, int resourceId) 566227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks throws IOException { 567227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks InputStream inputStream = context.getApplicationContext().getResources() 568227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks .openRawResource(resourceId); 569227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks XmlGraphReader reader = new XmlGraphReader(); 570227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks CommandStack commands = new CommandStack(context); 571227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks reader.parseInput(inputStream, commands); 572227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks commands.execute(); 573227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return commands.getBuilder(); 574227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 575227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks} 576227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 577