1   package com.frevvo.forms.cli.shell;
2   
3   import java.io.File;
4   import java.io.FileInputStream;
5   import java.io.FileNotFoundException;
6   import java.io.FileOutputStream;
7   import java.io.IOException;
8   import java.net.MalformedURLException;
9   import java.net.URL;
10  import java.util.ArrayList;
11  import java.util.HashMap;
12  import java.util.List;
13  import java.util.Map;
14  
15  import asg.cliche.Command;
16  
17  import com.frevvo.forms.cli.ApiHelper;
18  import com.frevvo.forms.cli.core.EntryShell;
19  import com.frevvo.forms.client.ControlTypeFeed;
20  import com.frevvo.forms.client.DocumentTypeFeed;
21  import com.frevvo.forms.client.FormTypeEntry;
22  import com.frevvo.forms.client.Helper;
23  import com.frevvo.forms.client.SubmissionFeed;
24  import com.google.gdata.data.Link;
25  import com.google.gdata.data.MediaContent;
26  import com.google.gdata.data.media.MediaSource;
27  import com.google.gdata.data.media.MediaStreamSource;
28  import com.google.gdata.util.ServiceException;
29  
30  /**
31   * Shell context for all commands related to form entries
32   */
33  public class FormTypeEntryShell extends EntryShell<FormTypeEntry> {
34  	public FormTypeEntryShell(FormTypeEntry entry) {
35  		super(entry.getTitle().getPlainText(), entry);
36  	}
37  
38  	@Command(name = "readonly", description = "UPDATE the readonly property (e.g. 'readonly {true|false}')")
39  	public String readonly(boolean value) {
40  		try {
41  			FormTypeEntry form = getEntry();
42  			form.setReadOnly(value);
43  			form = form.update();
44  			setEntry(form);
45  		} catch (Exception e) {
46  			return "Could not update formtype's visibility: " + e.getMessage();
47  		}
48  		return "Readonly updated to " + value;
49  	}
50  
51  	@Command(name = "snapshot", description = "OPEN form's PDF snapshot")
52  	public String snapshot() {
53  
54  		FormTypeEntry form = getEntry();
55  		Link snapshotLink = form.getSnapshotLink("application/pdf");
56  		openLink(snapshotLink);
57  
58  		return "Opening snapshot : " + snapshotLink.getHref();
59  	}
60  
61  	@Command(name = "new", description = "CREATE new form instance (e.g. 'new')")
62  	public String createInstanc() throws ServiceException, IOException {
63  		FormTypeEntry form = getEntry();
64  
65  		Map<String, Object> params = new HashMap<String, Object>();
66  		params.put(FormTypeEntry.FORMTYPE_DATA_PARAMETER, null);
67  		URL formInstanceUrl = form.createFormInstance(params, null);
68  
69  		return go(new FormInstanceShell(form, formInstanceUrl));
70  	}
71  
72  	@Command(name = "new", description = "CREATE new form instance (e.g. 'new p1=a,p2=10')")
73  	public String createInstanceFromData(String... data) {
74  		try {
75  			FormTypeEntry form = getEntry();
76  
77  			Map<String, Object> d = toFormData(data);
78  			Map<String, Object> params = new HashMap<String, Object>();
79  			params.put(FormTypeEntry.FORMTYPE_DATA_PARAMETER, d);
80  
81  			URL formInstanceUrl = form.createFormInstance(params, null);
82  
83  			return go(new FormInstanceShell(getEntry(), formInstanceUrl));
84  		} catch (Exception e) {
85  			return "Could not create " + getEntry().getKind() + " instance: "
86  					+ e.getMessage();
87  		}
88  	}
89  
90  	@Command(name = "newXml", description = "CREATE new form instance from XML (e.g. 'newXml /var/doc1.xml,/var/doc2.xml')")
91  	public String createInstanceFromXml(String... xmlDocPaths)
92  			throws ServiceException, IOException {
93  		try {
94  			List<MediaSource> mss = toMediaSources(xmlDocPaths);
95  
96  			FormTypeEntry entry = getEntry();
97  
98  			URL formInstanceUrl = entry.createFormInstance(null, mss);
99  
100 			return go(new FormInstanceShell(entry, formInstanceUrl));
101 		} catch (Exception e) {
102 			return "Could not create " + getEntry().getKind() + " instance: "
103 					+ e.getMessage();
104 		}
105 	}
106 
107 	@Command(name = "use", description = "USE form (e.g. 'use')")
108 	public String use() throws ServiceException {
109 
110 		FormTypeEntry form = getEntry();
111 		Link formLink = form.getFormTypeLink(null);
112 		Link l = openLink(formLink);
113 
114 		return "Using form: " + l.getHref();
115 	}
116 
117 	@Command(name = "edit", description = "EDIT form (e.g. 'edit')")
118 	public String edit() throws ServiceException {
119 
120 		FormTypeEntry form = getEntry();
121 		Link editorLink = form.getFormTypeEditorLink(null);
122 		Link l = openLink(editorLink);
123 
124 		return "Editing form: " + l.getHref();
125 	}
126 
127 	@Command(name = "schema", description = "LIST form controls (e.g. 'controls')")
128 	public String schema() throws MalformedURLException, IOException,
129 		ServiceException {
130 		
131 		String name = ApiHelper.getName(getEntry());
132 		String fileName = ApiHelper.nameToFileName(name);
133 		try {
134 			File file = File.createTempFile(fileName + "_", "_form.xsd");
135 			FileOutputStream fos = new FileOutputStream(file);
136 			try {
137 				FormTypeEntry form =getEntry();
138 				
139 				Link schemaLink = form.getFormTypeSchemaLink();
140 				MediaSource schemaSource = getService().getMedia(schemaLink.getHref());
141 				Helper.readStream(schemaSource.getInputStream(), fos);
142 
143 				return "Downloaded formtype schema: " + file;
144 			} catch (Exception e) {
145 				return "Could not download formtype schema: " + e.getMessage();
146 			} finally {
147 				fos.close();
148 			}
149 		} catch (Exception e) {
150 			return "Could not download formtype schema: " + e.getMessage();
151 		}
152 	}
153 	
154 	@Command(name = "controls", description = "LIST form controls (e.g. 'controls')")
155 	public String controls() throws MalformedURLException, IOException,
156 			ServiceException {
157 
158 		FormTypeEntry form = getEntry();
159 		ControlTypeFeed controls = form.getControlTypeFeed();
160 
161 		return go(new ControlTypeFeedShell(controls));
162 	}
163 
164 	@Command(name = "docs", description = "LIST form documents (e.g. 'docs')")
165 	public String doctypes() throws MalformedURLException, IOException,
166 			ServiceException {
167 
168 		FormTypeEntry form = getEntry();
169 		DocumentTypeFeed feed = form.getDocumentTypeFeed();
170 
171 		return go(new DocumentTypeFeedShell(form, feed));
172 	}
173 
174 	@Command(name = "subs", description = "LIST form submissions (e.g. 'subs')")
175 	public String subs() throws MalformedURLException, IOException,
176 			ServiceException {
177 
178 		FormTypeEntry form = getEntry();
179 		SubmissionFeed subs = form.getSubmissionFeed();
180 
181 		return go(new SubmissionFeedShell(subs));
182 	}
183 
184 	@Command(name = "down", description = "DOWNLOAD form (e.g. 'down')")
185 	public String download() throws IOException, ServiceException {
186 		String name = ApiHelper.getName(getEntry());
187 		String fileName = ApiHelper.nameToFileName(name);
188 		try {
189 			File file = File.createTempFile(fileName + "_", "_form.zip");
190 			FileOutputStream fos = new FileOutputStream(file);
191 			try {
192 				FormTypeEntry form = getEntry();
193 				MediaContent mc = (MediaContent) form.getContent();
194 				MediaSource ms = getService().getMedia(mc);
195 				Helper.readStream(ms.getInputStream(), fos);
196 
197 				return "Downloaded formtype: " + file;
198 			} catch (Exception e) {
199 				return "Could not download formtype: " + e.getMessage();
200 			} finally {
201 				fos.close();
202 			}
203 		} catch (Exception e) {
204 			return "Could not download formtype: " + e.getMessage();
205 		}
206 	}
207 
208 	@Override
209 	protected String print(FormTypeEntry entry) {
210 		return ApiHelper.print(getEntry());
211 	}
212 
213 	private Map<String, Object> toFormData(String[] data) {
214 		Map<String, Object> d = new HashMap<String, Object>();
215 		if (data != null) {
216 			for (String c : data) {
217 				String[] pair = c.split(":|=");
218 				if (pair.length == 2)
219 					d.put(pair[0], pair[1]);
220 			}
221 		}
222 		return d;
223 	}
224 
225 	private List<MediaSource> toMediaSources(String[] xmlDocPaths)
226 			throws FileNotFoundException {
227 		List<MediaSource> mss = new ArrayList<MediaSource>();
228 		if (xmlDocPaths != null) {
229 			for (int i = 0; i < xmlDocPaths.length; i++) {
230 				FileInputStream fis = new FileInputStream(xmlDocPaths[i]);
231 				MediaStreamSource ms = new MediaStreamSource(fis,
232 						"application/xml");
233 				ms.setName("Document" + i);
234 				mss.add(ms);
235 			}
236 		}
237 		return mss;
238 	}
239 }