2121import com .fasterxml .jackson .core .JsonProcessingException ;
2222import com .fasterxml .jackson .databind .ObjectMapper ;
2323import com .google .common .collect .Lists ;
24+ import com .google .common .collect .Maps ;
2425import com .google .inject .Inject ;
2526import lib .APIException ;
2627import lib .ApiClient ;
2728import lib .BreadcrumbList ;
29+ import lib .Version ;
2830import models .*;
31+ import models .api .requests .ExtractorImportRequest ;
32+ import models .api .requests .ExtractorListImportRequest ;
2933import play .Logger ;
3034import play .mvc .Result ;
3135
3236import java .io .IOException ;
37+ import java .util .ArrayList ;
3338import java .util .List ;
3439import java .util .Map ;
3540
@@ -166,23 +171,26 @@ public Result delete(String nodeId, String inputId, String extractorId) {
166171 }
167172 }
168173
169- public Result export (String nodeId , String inputId ) {
174+ public Result exportExtractors (String nodeId , String inputId ) {
170175 try {
171176 Node node = nodeService .loadNode (nodeId );
172177 Input input = node .getInput (inputId );
173178
174179 BreadcrumbList bc = standardBreadcrumbs (node , input );
175- bc .addCrumb ("Export" , routes .ExtractorsController .export (nodeId , inputId ));
180+ bc .addCrumb ("Export" , routes .ExtractorsController .exportExtractors (nodeId , inputId ));
176181
177- List <Map <String , Object >> exports = Lists .newArrayList ();
182+ Map <String , Object > result = Maps .newHashMap ();
183+ List <Map <String , Object >> extractors = Lists .newArrayList ();
178184 for (Extractor extractor : extractorService .all (node , input )) {
179- exports .add (extractor .export ());
185+ extractors .add (extractor .export ());
180186 }
187+ result .put ("extractors" , extractors );
188+ result .put ("version" , Version .VERSION .toString ());
181189
182190 String extractorExport = "[]" ;
183191 try {
184192 ObjectMapper om = new ObjectMapper ();
185- extractorExport = om .writeValueAsString (exports );
193+ extractorExport = om .writeValueAsString (result );
186194 } catch (JsonProcessingException e ) {
187195 Logger .error ("Could not generate extractor export." , e );
188196 }
@@ -204,6 +212,88 @@ public Result export(String nodeId, String inputId) {
204212 }
205213 }
206214
215+ public Result importExtractorsPage (String nodeId , String inputId ) {
216+ try {
217+ Node node = nodeService .loadNode (nodeId );
218+ Input input = node .getInput (inputId );
219+
220+ BreadcrumbList bc = standardBreadcrumbs (node , input );
221+ bc .addCrumb ("Import" , routes .ExtractorsController .importExtractorsPage (nodeId , inputId ));
222+
223+ return ok (views .html .system .inputs .extractors .importPage .render (
224+ currentUser (),
225+ bc ,
226+ node ,
227+ input
228+ ));
229+ } catch (IOException e ) {
230+ return status (500 , views .html .errors .error .render (ApiClient .ERROR_MSG_IO , e , request ()));
231+ } catch (APIException e ) {
232+ String message = "Could not fetch system information. We expected HTTP 200, but got a HTTP " + e .getHttpCode () + "." ;
233+ return status (500 , views .html .errors .error .render (message , e , request ()));
234+ } catch (NodeService .NodeNotFoundException e ) {
235+ return status (404 , views .html .errors .error .render (ApiClient .ERROR_MSG_NODE_NOT_FOUND , e , request ()));
236+ }
237+ }
238+
239+ public Result importExtractors (String nodeId , String inputId ) {
240+ Map <String , String > form = flattenFormUrlEncoded (request ().body ().asFormUrlEncoded ());
241+
242+ if (!form .containsKey ("extractors" ) || form .get ("extractors" ).isEmpty ()) {
243+ flash ("error" , "No JSON provided. Please fill out the import definition field." );
244+ return redirect (routes .ExtractorsController .importExtractorsPage (nodeId , inputId ));
245+ }
246+
247+ ExtractorListImportRequest elir ;
248+ try {
249+ ObjectMapper om = new ObjectMapper ();
250+ elir = om .readValue (form .get ("extractors" ), ExtractorListImportRequest .class );
251+ } catch (Exception e ) {
252+ Logger .error ("Could not read JSON." , e );
253+ flash ("error" , "Could not read JSON." );
254+ return redirect (routes .ExtractorsController .importExtractorsPage (nodeId , inputId ));
255+ }
256+
257+ /*
258+ * For future versions with breaking changes: check the "version" field in the ExtractorListImportRequest.
259+ *
260+ * Thank me later.
261+ */
262+
263+ int successes = 0 ;
264+ for (ExtractorImportRequest importRequest : elir .extractors ) {
265+ try {
266+ Node node = nodeService .loadNode (nodeId );
267+
268+ Extractor .Type type = Extractor .Type .valueOf (importRequest .extractorType .toUpperCase ());
269+
270+ Extractor extractor = extractorFactory .forCreate (
271+ Extractor .CursorStrategy .valueOf (importRequest .cursorStrategy .toUpperCase ()),
272+ importRequest .title ,
273+ importRequest .sourceField ,
274+ importRequest .targetField ,
275+ type ,
276+ currentUser (),
277+ Extractor .ConditionType .valueOf (importRequest .conditionType .toUpperCase ()),
278+ importRequest .conditionValue
279+ );
280+
281+ extractor .loadConfigFromImport (type , importRequest .extractorConfig );
282+ extractor .loadConvertersFromImport (importRequest .converters );
283+ extractor .setOrder (importRequest .order );
284+ extractor .create (node , node .getInput (inputId ));
285+ } catch (Exception e ) {
286+ Logger .error ("Could not import extractor. Continuing." , e );
287+ continue ;
288+ }
289+
290+ successes ++;
291+ }
292+
293+ flash ("success" , "Successfully imported " + successes + " of " + elir .extractors .size () + " extractors." );
294+ return redirect (routes .ExtractorsController .manage (nodeId , inputId ));
295+ }
296+
207297 private static BreadcrumbList standardBreadcrumbs (Node node , Input input ) {
208298 BreadcrumbList bc = new BreadcrumbList ();
209299 bc .addCrumb ("System" , routes .SystemController .index (0 ));
0 commit comments