001/*
002 * Copyright (c) 2009-2010 The Regents of the University of California.
003 * All rights reserved.
004 *
005 * '$Author: jianwu $'
006 * '$Date: 2012-05-14 23:47:32 +0000 (Mon, 14 May 2012) $' 
007 * '$Revision: 29830 $'
008 * 
009 * Permission is hereby granted, without written agreement and without
010 * license or royalty fees, to use, copy, modify, and distribute this
011 * software and its documentation for any purpose, provided that the above
012 * copyright notice and the following two paragraphs appear in all copies
013 * of this software.
014 *
015 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
016 * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
017 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
018 * THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
019 * SUCH DAMAGE.
020 *
021 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
022 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
023 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
024 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
025 * CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
026 * ENHANCEMENTS, OR MODIFICATIONS.
027 *
028 */
029
030package org.camera.service;
031
032import java.io.BufferedReader;
033import java.io.InputStreamReader;
034import java.net.URL;
035import java.util.HashMap;
036import java.util.Map;
037
038import org.kepler.actor.rest.ServiceUtils;
039
040import ptolemy.actor.TypedIOPort;
041import ptolemy.actor.lib.LimitedFiringSource;
042import ptolemy.data.StringToken;
043import ptolemy.data.expr.Parameter;
044import ptolemy.data.expr.StringParameter;
045import ptolemy.data.type.BaseType;
046import ptolemy.kernel.CompositeEntity;
047import ptolemy.kernel.util.Attribute;
048import ptolemy.kernel.util.IllegalActionException;
049import ptolemy.kernel.util.NameDuplicationException;
050
051//////////////////////////////////////////////////////////////////////////
052////CAMERAURLProcessor
053/**
054* This CAMERA specific URL Process automatically generates the
055* drop down based on the URL provided by the user from the StringParameter.
056* Choices only become visible after hitting the commit button and close the dialog and reopen
057* it by double clicking on the actor.
058* 
059* Selected value is programmatically saved in the moml file. Inside the
060* String Parameter that contains the URL a new property is created
061* dropdownValue of type StringParameter and value selected by the user from dropdown.
062* User must save the worfklow for changes to come in effect.
063* 
064* If the value of the StringParameter on the Canvas does not start
065* with http:// then actor outputs value contained in the StringParameter.
066* 
067*@author Madhu, SDSC  madhu@sdsc.edu
068*@version $Id
069*
070*/
071public class CAMERAURLProcessor extends LimitedFiringSource{
072        private static final long serialVersionUID = 1L;
073        
074        /* 
075         * URL of the service,it is supplied through String Parameter
076         * on the Canvas
077         */
078    public StringParameter urlValue;
079    
080    public Parameter delimiter;
081    
082    /* drop down value*/   
083    public StringParameter dropDownValue;
084    
085    public TypedIOPort outputPort;
086    
087    private String gVal = ServiceUtils.NOSPACE;
088    private String selectedValue =  ServiceUtils.NOSPACE;
089        private String parDelimiter = null;
090        private Map<String, String> keyValueMap = null;
091    
092    public CAMERAURLProcessor(CompositeEntity container,  String name)
093                                throws NameDuplicationException, IllegalActionException  {
094        
095        super(container, name);
096        
097        delimiter = new Parameter(this, "delimiter");
098                delimiter.setExpression(ServiceUtils.PARAMDELIMITER);
099                delimiter.setStringMode(true);
100        
101        urlValue = new StringParameter(this, "urlValue");
102        urlValue.setExpression(""); 
103        urlValue.setStringMode(true);   
104        
105        dropDownValue = new StringParameter(this, "dropDownValue");
106        dropDownValue.setExpression(""); 
107        dropDownValue.setStringMode(true);
108        
109        
110        
111        outputPort = new TypedIOPort(this, "outputPort", false, true);
112        outputPort.setTypeEquals(BaseType.STRING);
113    }
114    
115    
116    /* (non-Javadoc)
117     * @see ptolemy.actor.AtomicActor#fire()
118     */
119    @Override 
120    public void fire() throws IllegalActionException{
121        super.fire();
122        
123        StringToken tk = (StringToken)urlValue.getToken();
124        String urlVal = tk.stringValue();
125        if(urlVal.startsWith("http://")){
126                if(keyValueMap.size() == 0){
127                        outputPort.send(0, new StringToken(dropDownValue.getExpression()));
128                }else if(keyValueMap.containsKey(dropDownValue.getExpression())){
129                        String mapValue = dropDownValue.getExpression();
130                        if(ServiceUtils.checkEmptyString(mapValue)){
131                                outputPort.send(0, new StringToken(dropDownValue.getExpression()));
132                        }else{
133                                outputPort.send(0, new StringToken(keyValueMap.get(dropDownValue.getExpression())));
134                        }
135                }else {
136                        outputPort.send(0, new StringToken(dropDownValue.getExpression()));
137                }
138        }else{
139 //             process(ServiceUtils.NOSPACE);//Not sure, if it is needed.
140                outputPort.send(0, new StringToken(urlVal));
141        }
142    }
143    
144    @Override
145    public void attributeChanged(Attribute at){
146        
147        StringToken tk = null;
148        if(at == urlValue){
149 //             System.out.println( "++000++");
150                
151                StringBuilder contents = new StringBuilder();
152                String urlVal = null;
153                try{
154                        tk = (StringToken)urlValue.getToken();
155                }catch(IllegalActionException iae){
156                
157                        System.out.println("ILLEGAL EXCEPTION: " + "CAUGHT");
158                        iae.printStackTrace();
159                }
160                urlVal = tk.stringValue();
161 //             System.out.println("URLVALUE: " + urlVal + ": " + "++1111++");
162 //             System.out.println("GVALUE: " + gVal + ": " + "++1111++");
163                
164                if(gVal != ServiceUtils.NOSPACE && !urlVal.equals(gVal)){
165                        dropDownValue.removeAllChoices();
166                        dropDownValue.setExpression("");
167 //                     System.out.println("Inside remove choices: " + "++3333++");
168                }
169                if(urlVal.startsWith("http://") && !urlVal.equals(gVal) ){
170                        try {   
171//                              System.out.println("URLVALUE: " + urlVal + ": " + "++555++");
172                                BufferedReader input = null;                                                                    
173                                URL urlLocation = new URL(urlVal);
174                                input = new BufferedReader(new InputStreamReader(urlLocation.openStream()));
175                                        
176                                String line = null; //not declared within while loop    
177//                              System.out.println("URLVALUE: " + urlVal + ": " + "++666++");
178                                while (( line = input.readLine()) != null){
179                                        contents.append(line);
180                                        contents.append(System.getProperty("line.separator"));
181                                }
182 //                             System.out.println("URLVALUE: " + urlVal+ ": " + "++777++");
183                                String[] values = contents.toString().split(ServiceUtils.LINESEP);
184                                keyValueMap = new HashMap<String, String>();
185                                setParDelimiter();
186 //                             dropDownValue.addChoice(values[0]);
187                                for(String pVal: values){
188                                        System.out.println("PVAL: " + pVal);
189                                        System.out.println("DELIMITER: " + parDelimiter);
190                                        String[] splitValues = pVal.split(parDelimiter);
191                                        if(splitValues.length >= 2){
192                                                keyValueMap.put(splitValues[0], splitValues[1]);
193                                        }
194                                        dropDownValue.addChoice(splitValues[0]);
195                                }
196                                
197                        }catch(Exception e){
198                                System.err.println("exception is thrown when processing url:" + urlVal);
199                                e.printStackTrace();
200                        }
201                        gVal = urlVal;
202                }else if (!urlVal.startsWith("http://") || ServiceUtils.checkEmptyString(urlVal) ){
203 //                       System.out.println("URLVALUE: " + urlVal + ": " + "++4444++");
204                          gVal = urlVal;                                        
205                }
206                        
207        }else if(at == dropDownValue){
208                process(dropDownValue.getExpression(), parDelimiter);                   
209        }else {
210                try{
211                        super.attributeChanged(at);
212                }catch(IllegalActionException ioe){
213                        ioe.printStackTrace();
214                        System.out.println("PROBLEM WITH SUPER.ATTRIBUTECHANGED");
215                }
216        }
217        
218        
219    }
220    /**
221     * 
222     * @throws IllegalActionException
223     */
224    private void setParDelimiter() throws IllegalActionException {
225
226                String tmp = ((StringToken) delimiter.getToken()).stringValue().trim();
227
228                if (!ServiceUtils.checkEmptyString(tmp)) {
229
230                        parDelimiter = tmp;
231                } else {
232                        parDelimiter = ServiceUtils.PARAMDELIMITER;
233                }
234        }
235    /**
236     * This method saves the selected value in the moml file.
237     * It creates the property dropdownValue id it does not exist and
238     * sets the value. If property already exists then value is simply 
239     * updated if user makes any changes.
240     * 
241     * @param param it is the value selected made by the user.
242     */
243    private void process(String param, String delimiterValue){
244        if(ServiceUtils.checkEmptyString(urlValue.getExpression().trim())){
245                return;
246        }
247 //     System.out.println("SUBSTRING: " + urlValue.getExpression().trim().substring(1));
248                StringParameter a = (StringParameter)getContainer().getAttribute(urlValue.getExpression().substring(1));
249                StringParameter SelectedValue = (StringParameter)a.getAttribute("SelectedValue");
250                StringParameter DelimiterValue = (StringParameter)a.getAttribute("DelimiterValue");
251                if(SelectedValue== null){
252                        try{
253//                              System.out.println("I am in if block");
254                                SelectedValue = new StringParameter(a,"SelectedValue");
255                                SelectedValue.setExpression(param);
256                                DelimiterValue = new StringParameter(a,"DelimiterValue");
257                                DelimiterValue.setExpression(delimiterValue);
258                        }catch(NameDuplicationException nde){
259                                System.out.println("NAME DUPLICATION EXCEPTION CAUGHT");
260                                nde.printStackTrace();
261                        }catch(IllegalActionException iae){
262                                System.out.println("CAUGHT ILLEGAL EXCEPTION");
263                                iae.printStackTrace();
264                        }
265                }else{                  
266                                SelectedValue.setExpression(dropDownValue.getExpression());
267                                DelimiterValue.setExpression(parDelimiter);
268                }       
269    }
270        
271}