diff --git a/src/main/java/com/ibm/watson/developer_cloud/tone_analyzer/v3/ToneAnalyzer.java b/src/main/java/com/ibm/watson/developer_cloud/tone_analyzer/v3/ToneAnalyzer.java new file mode 100644 index 00000000000..628ac7c05dd --- /dev/null +++ b/src/main/java/com/ibm/watson/developer_cloud/tone_analyzer/v3/ToneAnalyzer.java @@ -0,0 +1,81 @@ +/** + * Copyright 2015 IBM Corp. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ +package com.ibm.watson.developer_cloud.tone_analyzer.v3; + +import java.lang.reflect.Type; +import java.util.List; + +import com.google.gson.JsonObject; +import com.google.gson.reflect.TypeToken; +import com.ibm.watson.developer_cloud.http.HttpMediaType; +import com.ibm.watson.developer_cloud.http.RequestBuilder; +import com.ibm.watson.developer_cloud.service.WatsonService; +import com.ibm.watson.developer_cloud.tone_analyzer.v1.model.Scorecard; +import com.ibm.watson.developer_cloud.tone_analyzer.v1.model.SynonymOptions; +import com.ibm.watson.developer_cloud.tone_analyzer.v1.model.SynonymResult; +import com.ibm.watson.developer_cloud.tone_analyzer.v1.model.Tone; +import com.ibm.watson.developer_cloud.tone_analyzer.v3.model.ToneAnalysis; +import com.ibm.watson.developer_cloud.util.GsonSingleton; +import com.ibm.watson.developer_cloud.util.ResponseUtil; +import com.squareup.okhttp.Request; +import com.squareup.okhttp.Response; + +/** + * The IBM Watson The Tone Analyzer service uses linguistic analysis to detect emotional tones, + * social propensities, and writing styles in written communication. Then it offers suggestions to + * help the writer improve their intended language tones. + * + * @version v1 + * @see + * Tone Analyzer + */ +public class ToneAnalyzer extends WatsonService { + + private static final String PATH_TONE = "/v3/tone"; + private static final String TEXT = "text"; + private static final String URL = + "https://gateway.watsonplatform.net/tone-analyzer-beta/api"; + + /** + * Instantiates a new Tone Analyzer service. + */ + public ToneAnalyzer() { + super("tone_analyzer"); + setEndPoint(URL); + } + + + /** + * Analyzes the "tone" of a piece of text. The message is analyzed from several tones (social + * tone, emotional tone, writing tone), and for each of them various traits are derived (such as + * conscientiousness, agreeableness, openness). + * + * @param text The text to analyze + * @return the {@link Tone} with the response + * + */ + public ToneAnalysis getTone(final String text) { + + if (text == null || text.isEmpty()) + throw new IllegalArgumentException("text cannot be null or empty"); + + final JsonObject contentJson = new JsonObject(); + contentJson.addProperty(TEXT, text); + + final Request request = RequestBuilder.post(PATH_TONE).withBodyJson(contentJson).build(); + return executeRequest(request, ToneAnalysis.class); + } + +} diff --git a/src/main/java/com/ibm/watson/developer_cloud/tone_analyzer/v3/model/ElementTone.java b/src/main/java/com/ibm/watson/developer_cloud/tone_analyzer/v3/model/ElementTone.java new file mode 100644 index 00000000000..42abcc15950 --- /dev/null +++ b/src/main/java/com/ibm/watson/developer_cloud/tone_analyzer/v3/model/ElementTone.java @@ -0,0 +1,32 @@ +package com.ibm.watson.developer_cloud.tone_analyzer.v3.model; + +import java.util.ArrayList; +import java.util.List; + +import com.ibm.watson.developer_cloud.service.model.GenericModel; + +/** + * This object represents the results of Tone analysis on an element; which may be a document or a sentence. + * Its structure is a 2-level tree, with tone categories in the top level and the individual tones (and their + * scores) in leaves. + * + * @author Hernan Badenes + * + */ +public class ElementTone extends GenericModel { + + List tones = new ArrayList(); + + public List getTones() { + return tones; + } + + public void setTones(List tones) { + this.tones = tones; + } + + public void addTone(ToneCategory tone) { + this.tones.add(tone); + } + +} diff --git a/src/main/java/com/ibm/watson/developer_cloud/tone_analyzer/v3/model/SentenceAnalysis.java b/src/main/java/com/ibm/watson/developer_cloud/tone_analyzer/v3/model/SentenceAnalysis.java new file mode 100644 index 00000000000..8dba64ef01f --- /dev/null +++ b/src/main/java/com/ibm/watson/developer_cloud/tone_analyzer/v3/model/SentenceAnalysis.java @@ -0,0 +1,65 @@ +package com.ibm.watson.developer_cloud.tone_analyzer.v3.model; + +import java.util.ArrayList; +import java.util.List; + +import com.ibm.watson.developer_cloud.service.model.GenericModel; + +/** + * This element contains the result of analyzing an individual sentence. It contains a list of ToneCategory + * objects which is the actual result, and also some metadata about the sentence: The original text (if it needs + * to be tracked back), and the position of the sentence in the original text (as index of first and last + * character). + * + * @author Hernan Badenes + * + */ +public class SentenceAnalysis extends GenericModel { + + long sentence_id; + + int charFrom; + + int charTo; + + String text; + + List tones = new ArrayList(); + + public SentenceAnalysis() { + } + + public SentenceAnalysis(long sentence_id, int charFrom, int charTo, String text) { + super(); + this.sentence_id = sentence_id; + this.charFrom = charFrom; + this.charTo = charTo; + this.text = text; + } + + public long getSentence_id() { + return sentence_id; + } + + public int getCharFrom() { + return charFrom; + } + + public int getCharTo() { + return charTo; + } + + public String getText() { + return text; + } + + public void setTones(List tones) { + this.tones = tones; + } + + public void addTone(ToneCategory tone) { + this.tones.add(tone); + } + + +} \ No newline at end of file diff --git a/src/main/java/com/ibm/watson/developer_cloud/tone_analyzer/v3/model/ToneAnalysis.java b/src/main/java/com/ibm/watson/developer_cloud/tone_analyzer/v3/model/ToneAnalysis.java new file mode 100644 index 00000000000..e39a655d0fd --- /dev/null +++ b/src/main/java/com/ibm/watson/developer_cloud/tone_analyzer/v3/model/ToneAnalysis.java @@ -0,0 +1,42 @@ +package com.ibm.watson.developer_cloud.tone_analyzer.v3.model; + +import java.util.List; + +import com.ibm.watson.developer_cloud.service.model.GenericModel; + +/** + * + * Main object containing the result of running Tone Analyzer on a document. It contains both + * the sentence-level and document-level results. + * + * @author Hernan Badenes + * + */ +public class ToneAnalysis extends GenericModel { + + ElementTone documentTone; + + List sentencesTone; + + public ElementTone getDocumentTone() { + return documentTone; + } + + public void setDocumentTone(ElementTone documentTone) { + this.documentTone = documentTone; + } + + public List getSentencesTone() { + return sentencesTone; + } + + public void setSentencesTone(List sentencesTone) { + this.sentencesTone = sentencesTone; + } + + public void addSentencesTone(SentenceAnalysis analysis) { + this.sentencesTone.add(analysis); + } + + +} diff --git a/src/main/java/com/ibm/watson/developer_cloud/tone_analyzer/v3/model/ToneCategory.java b/src/main/java/com/ibm/watson/developer_cloud/tone_analyzer/v3/model/ToneCategory.java new file mode 100644 index 00000000000..7893d448e0c --- /dev/null +++ b/src/main/java/com/ibm/watson/developer_cloud/tone_analyzer/v3/model/ToneCategory.java @@ -0,0 +1,56 @@ +package com.ibm.watson.developer_cloud.tone_analyzer.v3.model; + +import java.util.ArrayList; +import java.util.List; + +import com.ibm.watson.developer_cloud.service.model.GenericModel; + +/** + * This object represents a top levle tone (or Tone Category) from the list of Writing Tone, Emotion Tone or Social Tone. + * It holds a list of scores for individual Tones. + * + * @author Hernan Badenes + * + */ +public class ToneCategory extends GenericModel { + + // The ID of this category. It can referred to from several places in the API input/output. + String id; + + // A human-readable, localized name for this category. + String name; + + // The list of tone scores in this category + List tones = new ArrayList(); + + public ToneCategory() { + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public List getTones() { + return tones; + } + + public void setTones(List tones) { + this.tones = tones; + } + + public void addTone(ToneScore score) { + this.tones.add(score); + } +} diff --git a/src/main/java/com/ibm/watson/developer_cloud/tone_analyzer/v3/model/ToneScore.java b/src/main/java/com/ibm/watson/developer_cloud/tone_analyzer/v3/model/ToneScore.java new file mode 100644 index 00000000000..79939ed2862 --- /dev/null +++ b/src/main/java/com/ibm/watson/developer_cloud/tone_analyzer/v3/model/ToneScore.java @@ -0,0 +1,55 @@ +package com.ibm.watson.developer_cloud.tone_analyzer.v3.model; + +import com.ibm.watson.developer_cloud.service.model.GenericModel; + +/* + * Object representing scoring of a single Tone (of any category) on our responses. It contains the Tone ID, a score, and optionally + * a list of evidences. + * + * @author Hernan Badenes + */ +public class ToneScore extends GenericModel { + + String tone_id; + + String tone_name; + + Double score; + + public ToneScore() { + + } + + public ToneScore(String toneId, String toneName, Double score) { + super(); + this.tone_id = toneId; + this.tone_name = toneName; + this.score = score; + } + + public String getToneId() { + return tone_id; + } + + public String getToneName() { + return tone_name; + } + + public Double getScore() { + return score; + } + + public void setToneId(String toneId) { + this.tone_id = toneId; + } + + public void setToneName(String toneName) { + this.tone_name = toneName; + } + + public void setScore(Double score) { + this.score = score; + } + + +} diff --git a/src/main/java/com/ibm/watson/developer_cloud/tone_analyzer/v3/package-info.java b/src/main/java/com/ibm/watson/developer_cloud/tone_analyzer/v3/package-info.java new file mode 100644 index 00000000000..8f90dc1dfad --- /dev/null +++ b/src/main/java/com/ibm/watson/developer_cloud/tone_analyzer/v3/package-info.java @@ -0,0 +1,15 @@ +/** + * Copyright 2015 IBM Corp. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ +package com.ibm.watson.developer_cloud.tone_analyzer.v3; + diff --git a/src/test/java/com/ibm/watson/developer_cloud/tone_analyzer/v3/ToneAnalyzerIT.java b/src/test/java/com/ibm/watson/developer_cloud/tone_analyzer/v3/ToneAnalyzerIT.java new file mode 100644 index 00000000000..c22faab260b --- /dev/null +++ b/src/test/java/com/ibm/watson/developer_cloud/tone_analyzer/v3/ToneAnalyzerIT.java @@ -0,0 +1,67 @@ +/** + * Copyright 2015 IBM Corp. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ +package com.ibm.watson.developer_cloud.tone_analyzer.v3; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.ibm.watson.developer_cloud.WatsonServiceTest; +import com.ibm.watson.developer_cloud.tone_analyzer.v3.model.ToneAnalysis; + +/** + * The Class ToneAnalyzerTest. + */ +public class ToneAnalyzerIT extends WatsonServiceTest { + + /** The service. */ + private ToneAnalyzer service; + + /* + * (non-Javadoc) + * + * @see com.ibm.watson.developer_cloud.WatsonServiceTest#setUp() + */ + @Override + @Before + public void setUp() throws Exception { + super.setUp(); + service = new ToneAnalyzer(); + service.setUsernameAndPassword(getValidProperty("tone_analyzer.username"), + getValidProperty("tone_analyzer.password")); + service.setEndPoint(getValidProperty("tone_analyzer.url")); + service.setDefaultHeaders(getDefaultHeaders()); + + } + + @Test + public void testGetTone() { + final String text = + "I know the times are difficult! Our sales have been " + + "disappointing for the past three quarters for our data analytics " + + "product suite. We have a competitive data analytics product " + + "suite in the industry. But we need to do our job selling it! "; + + + // Call the service and get the tone + final ToneAnalysis tone = service.getTone(text); + Assert.assertNotNull(tone); + Assert.assertNotNull(tone.getDocumentTone()); + Assert.assertEquals(3, tone.getDocumentTone().getTones().size()); + Assert.assertNotNull(tone.getSentencesTone()); + Assert.assertEquals(1, tone.getSentencesTone().size()); + Assert.assertNotNull(tone.getSentencesTone().get(0).getText()); + } + +} diff --git a/src/test/java/com/ibm/watson/developer_cloud/tone_analyzer/v3/ToneAnalyzerTest.java b/src/test/java/com/ibm/watson/developer_cloud/tone_analyzer/v3/ToneAnalyzerTest.java new file mode 100644 index 00000000000..3bea81b8606 --- /dev/null +++ b/src/test/java/com/ibm/watson/developer_cloud/tone_analyzer/v3/ToneAnalyzerTest.java @@ -0,0 +1,161 @@ +/** + * Copyright 2015 IBM Corp. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ +package com.ibm.watson.developer_cloud.tone_analyzer.v3; + +import static org.mockserver.model.HttpRequest.request; +import static org.mockserver.model.HttpResponse.response; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.mockserver.model.Header; + +import com.google.gson.JsonObject; +import com.ibm.watson.developer_cloud.WatsonServiceUnitTest; +import com.ibm.watson.developer_cloud.http.HttpMediaType; +import com.ibm.watson.developer_cloud.tone_analyzer.v3.model.ElementTone; +import com.ibm.watson.developer_cloud.tone_analyzer.v3.model.SentenceAnalysis; +import com.ibm.watson.developer_cloud.tone_analyzer.v3.model.ToneAnalysis; +import com.ibm.watson.developer_cloud.tone_analyzer.v3.model.ToneCategory; +import com.ibm.watson.developer_cloud.tone_analyzer.v3.model.ToneScore; +import com.ibm.watson.developer_cloud.util.GsonSingleton; + +import io.netty.handler.codec.http.HttpHeaders; + +/** + * The Class ToneAnalyzerTest. + */ +@SuppressWarnings("serial") +public class ToneAnalyzerTest extends WatsonServiceUnitTest { + + private final static String TONE_PATH = "/v3/tone"; + + /** The service. */ + private ToneAnalyzer service; + + /* + * (non-Javadoc) + * + * @see com.ibm.watson.developer_cloud.WatsonServiceTest#setUp() + */ + @Override + @Before + public void setUp() throws Exception { + super.setUp(); + service = new ToneAnalyzer(); + service.setApiKey(""); + service.setEndPoint(MOCK_SERVER_URL); + + } + + /** + * Test get tone. + */ + @Test + public void testGetTone() { + final String text = + "I know the times are difficult! Our sales have been " + + "disappointing for the past three quarters for our data analytics " + + "product suite. We have a competitive data analytics product " + + "suite in the industry. But we need to do our job selling it! "; + + final ToneAnalysis response = new ToneAnalysis(); + + final ElementTone docTone = new ElementTone(); + docTone.addTone(buildEmotionTone()); + docTone.addTone(buildWritingTone()); + docTone.addTone(buildSocialTone()); + + List sentences = new ArrayList(); + response.setSentencesTone(sentences); + + final SentenceAnalysis sentence = new SentenceAnalysis(0, 0, text.length(), text); + sentence.addTone(buildEmotionTone()); + sentence.addTone(buildWritingTone()); + sentence.addTone(buildSocialTone()); + + final JsonObject contentJson = new JsonObject(); + contentJson.addProperty("text", text); + + mockServer + .when(request().withMethod(POST).withPath(TONE_PATH).withBody(contentJson.toString())) + .respond( + response().withHeaders( + new Header(HttpHeaders.Names.CONTENT_TYPE, HttpMediaType.APPLICATION_JSON)) + .withBody(GsonSingleton.getGson().toJson(response))); + + // Call the service and get the tone + final ToneAnalysis tone = service.getTone(text); + Assert.assertNotNull(tone); + Assert.assertNotNull(tone.getDocumentTone()); + Assert.assertEquals(3, tone.getDocumentTone().getTones().size()); + Assert.assertNotNull(tone.getSentencesTone()); + Assert.assertEquals(1, tone.getSentencesTone().size()); + Assert.assertNotNull(tone.getSentencesTone().get(0).getText()); + Assert.assertEquals(tone, response); + + } + + private ToneCategory buildEmotionTone() { + final ToneCategory ret = new ToneCategory(); + ret.setId("emotion_tone"); + ret.setName("Emotion Tone"); + List tones = new ArrayList(); + tones.add(new ToneScore("anger", "Anger", 0.1)); + tones.add(new ToneScore("disgust", "Disgust", 0.2)); + tones.add(new ToneScore("fear", "Fear", 0.3)); + tones.add(new ToneScore("joy", "Joy", 0.4)); + tones.add(new ToneScore("sadness", "Sadness", 0.0)); + ret.setTones(tones); + return null; + } + + private ToneCategory buildWritingTone() { + final ToneCategory ret = new ToneCategory(); + ret.setId("writing_tone"); + ret.setName("Writing Tone"); + List tones = new ArrayList(); + tones.add(new ToneScore("analytical", "Analytical", 0.2)); + tones.add(new ToneScore("confident", "Confident", 0.3)); + tones.add(new ToneScore("tentative", "Tentative", 0.4)); + ret.setTones(tones); + return null; + } + + private ToneCategory buildSocialTone() { + final ToneCategory ret = new ToneCategory(); + ret.setId("social_tone"); + ret.setName("Social Tone"); + List tones = new ArrayList(); + tones.add(new ToneScore("openness_big5", "Openness", 0.1)); + tones.add(new ToneScore("conscientiousness_big5", "Conscientiousness", 0.2)); + tones.add(new ToneScore("extraversion_big5", "Extraversion", 0.3)); + tones.add(new ToneScore("agreeableness_big5", "Agreeableness", 0.4)); + tones.add(new ToneScore("neuroticism_big5", "Emotional Range", 0.5)); + ret.setTones(tones); + return null; + } + +/** + * Test tone with null. + */ + @Test(expected = IllegalArgumentException.class) + public void testGetToneWithNull() { + service.getTone(null); + } + +}