3232import com .ibm .watson .developer_cloud .visual_recognition .v3 .model .GetCoreMlModelOptions ;
3333import com .ibm .watson .developer_cloud .visual_recognition .v3 .model .ListClassifiersOptions ;
3434import com .ibm .watson .developer_cloud .visual_recognition .v3 .model .UpdateClassifierOptions ;
35- import java .io .InputStream ;
3635import okhttp3 .MultipartBody ;
3736import okhttp3 .RequestBody ;
3837
38+ import java .io .File ;
39+ import java .io .InputStream ;
40+
3941/**
4042 * The IBM Watson™ Visual Recognition service uses deep learning algorithms to identify scenes, objects, and faces
4143 * in images you upload to the service. You can create and train a custom classifier to identify subjects that suit
@@ -137,9 +139,13 @@ public VisualRecognition(String versionDate, IamOptions iamOptions) {
137139 */
138140 public ServiceCall <ClassifiedImages > classify (ClassifyOptions classifyOptions ) {
139141 Validator .notNull (classifyOptions , "classifyOptions cannot be null" );
140- Validator .isTrue ((classifyOptions .imagesFile () != null ) || (classifyOptions .url () != null ) || (classifyOptions
141- .threshold () != null ) || (classifyOptions .owners () != null ) || (classifyOptions .classifierIds () != null ),
142- "At least one of imagesFile, url, threshold, owners, or classifierIds must be supplied." );
142+ Validator .isTrue ((classifyOptions .imagesFile () != null )
143+ || (classifyOptions .url () != null )
144+ || (classifyOptions .threshold () != null )
145+ || (classifyOptions .owners () != null )
146+ || (classifyOptions .classifierIds () != null )
147+ || (classifyOptions .parameters () != null ),
148+ "At least one of imagesFile, url, threshold, owners, classifierIds, or parameters must be supplied." );
143149 String [] pathSegments = { "v3/classify" };
144150 RequestBuilder builder = RequestBuilder .post (RequestBuilder .constructHttpUrl (getEndPoint (), pathSegments ));
145151 builder .query (VERSION , versionDate );
@@ -153,6 +159,9 @@ public ServiceCall<ClassifiedImages> classify(ClassifyOptions classifyOptions) {
153159 .imagesFileContentType ());
154160 multipartBuilder .addFormDataPart ("images_file" , classifyOptions .imagesFilename (), imagesFileBody );
155161 }
162+ if (classifyOptions .parameters () != null ) {
163+ multipartBuilder .addFormDataPart ("parameters" , classifyOptions .parameters ());
164+ }
156165 if (classifyOptions .url () != null ) {
157166 multipartBuilder .addFormDataPart ("url" , classifyOptions .url ());
158167 }
@@ -200,8 +209,10 @@ public ServiceCall<ClassifiedImages> classify() {
200209 */
201210 public ServiceCall <DetectedFaces > detectFaces (DetectFacesOptions detectFacesOptions ) {
202211 Validator .notNull (detectFacesOptions , "detectFacesOptions cannot be null" );
203- Validator .isTrue ((detectFacesOptions .imagesFile () != null ) || (detectFacesOptions .url () != null ),
204- "At least one of imagesFile or url must be supplied." );
212+ Validator .isTrue ((detectFacesOptions .imagesFile () != null )
213+ || (detectFacesOptions .url () != null )
214+ || (detectFacesOptions .parameters () != null ),
215+ "At least one of imagesFile, url, or parameters must be supplied." );
205216 String [] pathSegments = { "v3/detect_faces" };
206217 RequestBuilder builder = RequestBuilder .post (RequestBuilder .constructHttpUrl (getEndPoint (), pathSegments ));
207218 builder .query (VERSION , versionDate );
@@ -212,6 +223,9 @@ public ServiceCall<DetectedFaces> detectFaces(DetectFacesOptions detectFacesOpti
212223 .imagesFileContentType ());
213224 multipartBuilder .addFormDataPart ("images_file" , detectFacesOptions .imagesFilename (), imagesFileBody );
214225 }
226+ if (detectFacesOptions .parameters () != null ) {
227+ multipartBuilder .addFormDataPart ("parameters" , detectFacesOptions .parameters ());
228+ }
215229 if (detectFacesOptions .url () != null ) {
216230 multipartBuilder .addFormDataPart ("url" , detectFacesOptions .url ());
217231 }
@@ -261,10 +275,13 @@ public ServiceCall<Classifier> createClassifier(CreateClassifierOptions createCl
261275 MultipartBody .Builder multipartBuilder = new MultipartBody .Builder ();
262276 multipartBuilder .setType (MultipartBody .FORM );
263277 multipartBuilder .addFormDataPart ("name" , createClassifierOptions .name ());
264- RequestBody classnamePositiveExamplesBody = RequestUtils .inputStreamBody (createClassifierOptions
265- .classnamePositiveExamples (), "application/octet-stream" );
266- multipartBuilder .addFormDataPart ("classname_positive_examples" , createClassifierOptions
267- .classnamePositiveExamplesFilename (), classnamePositiveExamplesBody );
278+ // Classes
279+ for (String className : createClassifierOptions .classNames ()) {
280+ String dataName = className + "_positive_examples" ;
281+ File positiveExamples = createClassifierOptions .positiveExamplesByClassName (className );
282+ RequestBody body = RequestUtils .fileBody (positiveExamples , "application/octet-stream" );
283+ multipartBuilder .addFormDataPart (dataName , positiveExamples .getName (), body );
284+ }
268285 if (createClassifierOptions .negativeExamples () != null ) {
269286 RequestBody negativeExamplesBody = RequestUtils .inputStreamBody (createClassifierOptions .negativeExamples (),
270287 "application/octet-stream" );
@@ -342,7 +359,8 @@ public ServiceCall<Classifiers> listClassifiers() {
342359 * Update a custom classifier by adding new positive or negative classes (examples) or by adding new images to
343360 * existing classes. You must supply at least one set of positive or negative examples. For details, see [Updating
344361 * custom
345- * classifiers](https://console.bluemix.net/docs/services/visual-recognition/customizing.html#updating-custom-classifiers).
362+ * classifiers]
363+ * (https://console.bluemix.net/docs/services/visual-recognition/customizing.html#updating-custom-classifiers).
346364 *
347365 * Encode all names in UTF-8 if they contain non-ASCII characters (.zip and image file names, and classifier and class
348366 * names). The service assumes UTF-8 encoding if it encounters non-ASCII characters.
@@ -356,7 +374,7 @@ public ServiceCall<Classifiers> listClassifiers() {
356374 */
357375 public ServiceCall <Classifier > updateClassifier (UpdateClassifierOptions updateClassifierOptions ) {
358376 Validator .notNull (updateClassifierOptions , "updateClassifierOptions cannot be null" );
359- Validator .isTrue ((updateClassifierOptions .classnamePositiveExamples () != null ) || (updateClassifierOptions
377+ Validator .isTrue ((updateClassifierOptions .classNames (). size () > 0 ) || (updateClassifierOptions
360378 .negativeExamples () != null ),
361379 "At least one of classnamePositiveExamples or negativeExamples must be supplied." );
362380 String [] pathSegments = { "v3/classifiers" };
@@ -366,11 +384,12 @@ public ServiceCall<Classifier> updateClassifier(UpdateClassifierOptions updateCl
366384 builder .query (VERSION , versionDate );
367385 MultipartBody .Builder multipartBuilder = new MultipartBody .Builder ();
368386 multipartBuilder .setType (MultipartBody .FORM );
369- if (updateClassifierOptions .classnamePositiveExamples () != null ) {
370- RequestBody classnamePositiveExamplesBody = RequestUtils .inputStreamBody (updateClassifierOptions
371- .classnamePositiveExamples (), "application/octet-stream" );
372- multipartBuilder .addFormDataPart ("classname_positive_examples" , updateClassifierOptions
373- .classnamePositiveExamplesFilename (), classnamePositiveExamplesBody );
387+ // Classes
388+ for (String className : updateClassifierOptions .classNames ()) {
389+ String dataName = className + "_positive_examples" ;
390+ File positiveExamples = updateClassifierOptions .positiveExamplesByClassName (className );
391+ RequestBody body = RequestUtils .fileBody (positiveExamples , "application/octet-stream" );
392+ multipartBuilder .addFormDataPart (dataName , positiveExamples .getName (), body );
374393 }
375394 if (updateClassifierOptions .negativeExamples () != null ) {
376395 RequestBody negativeExamplesBody = RequestUtils .inputStreamBody (updateClassifierOptions .negativeExamples (),
0 commit comments