├── LICENSE ├── README.md ├── pom.xml └── src ├── main ├── java │ ├── client │ │ ├── NifInput.java │ │ ├── NifOutput.java │ │ ├── ResourceClient.java │ │ └── ServiceClient.java │ ├── samples │ │ ├── Application.java │ │ ├── NegativeWordsMatcher.java │ │ ├── PositiveWordsMatcher.java │ │ ├── Server.java │ │ ├── SimpleSentimentAnalyzer.java │ │ ├── SparqlQuery.java │ │ ├── SparqlQueryFactory.java │ │ └── WordsMatcher.java │ └── utils │ │ ├── TextMatcher.java │ │ └── TextNormalizer.java └── resources │ ├── application.properties │ └── logback.xml └── test ├── java ├── client │ └── ServiceClientTest.java └── samples │ └── ApplicationTests.java └── resources └── test.properties /LICENSE: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | 9 | This version of the GNU Lesser General Public License incorporates 10 | the terms and conditions of version 3 of the GNU General Public 11 | License, supplemented by the additional permissions listed below. 12 | 13 | 0. Additional Definitions. 14 | 15 | As used herein, "this License" refers to version 3 of the GNU Lesser 16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 17 | General Public License. 18 | 19 | "The Library" refers to a covered work governed by this License, 20 | other than an Application or a Combined Work as defined below. 21 | 22 | An "Application" is any work that makes use of an interface provided 23 | by the Library, but which is not otherwise based on the Library. 24 | Defining a subclass of a class defined by the Library is deemed a mode 25 | of using an interface provided by the Library. 26 | 27 | A "Combined Work" is a work produced by combining or linking an 28 | Application with the Library. The particular version of the Library 29 | with which the Combined Work was made is also called the "Linked 30 | Version". 31 | 32 | The "Minimal Corresponding Source" for a Combined Work means the 33 | Corresponding Source for the Combined Work, excluding any source code 34 | for portions of the Combined Work that, considered in isolation, are 35 | based on the Application, and not on the Linked Version. 36 | 37 | The "Corresponding Application Code" for a Combined Work means the 38 | object code and/or source code for the Application, including any data 39 | and utility programs needed for reproducing the Combined Work from the 40 | Application, but excluding the System Libraries of the Combined Work. 41 | 42 | 1. Exception to Section 3 of the GNU GPL. 43 | 44 | You may convey a covered work under sections 3 and 4 of this License 45 | without being bound by section 3 of the GNU GPL. 46 | 47 | 2. Conveying Modified Versions. 48 | 49 | If you modify a copy of the Library, and, in your modifications, a 50 | facility refers to a function or data to be supplied by an Application 51 | that uses the facility (other than as an argument passed when the 52 | facility is invoked), then you may convey a copy of the modified 53 | version: 54 | 55 | a) under this License, provided that you make a good faith effort to 56 | ensure that, in the event an Application does not supply the 57 | function or data, the facility still operates, and performs 58 | whatever part of its purpose remains meaningful, or 59 | 60 | b) under the GNU GPL, with none of the additional permissions of 61 | this License applicable to that copy. 62 | 63 | 3. Object Code Incorporating Material from Library Header Files. 64 | 65 | The object code form of an Application may incorporate material from 66 | a header file that is part of the Library. You may convey such object 67 | code under terms of your choice, provided that, if the incorporated 68 | material is not limited to numerical parameters, data structure 69 | layouts and accessors, or small macros, inline functions and templates 70 | (ten or fewer lines in length), you do both of the following: 71 | 72 | a) Give prominent notice with each copy of the object code that the 73 | Library is used in it and that the Library and its use are 74 | covered by this License. 75 | 76 | b) Accompany the object code with a copy of the GNU GPL and this license 77 | document. 78 | 79 | 4. Combined Works. 80 | 81 | You may convey a Combined Work under terms of your choice that, 82 | taken together, effectively do not restrict modification of the 83 | portions of the Library contained in the Combined Work and reverse 84 | engineering for debugging such modifications, if you also do each of 85 | the following: 86 | 87 | a) Give prominent notice with each copy of the Combined Work that 88 | the Library is used in it and that the Library and its use are 89 | covered by this License. 90 | 91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 92 | document. 93 | 94 | c) For a Combined Work that displays copyright notices during 95 | execution, include the copyright notice for the Library among 96 | these notices, as well as a reference directing the user to the 97 | copies of the GNU GPL and this license document. 98 | 99 | d) Do one of the following: 100 | 101 | 0) Convey the Minimal Corresponding Source under the terms of this 102 | License, and the Corresponding Application Code in a form 103 | suitable for, and under terms that permit, the user to 104 | recombine or relink the Application with a modified version of 105 | the Linked Version to produce a modified Combined Work, in the 106 | manner specified by section 6 of the GNU GPL for conveying 107 | Corresponding Source. 108 | 109 | 1) Use a suitable shared library mechanism for linking with the 110 | Library. A suitable mechanism is one that (a) uses at run time 111 | a copy of the Library already present on the user's computer 112 | system, and (b) will operate properly with a modified version 113 | of the Library that is interface-compatible with the Linked 114 | Version. 115 | 116 | e) Provide Installation Information, but only if you would otherwise 117 | be required to provide such information under section 6 of the 118 | GNU GPL, and only to the extent that such information is 119 | necessary to install and execute a modified version of the 120 | Combined Work produced by recombining or relinking the 121 | Application with a modified version of the Linked Version. (If 122 | you use option 4d0, the Installation Information must accompany 123 | the Minimal Corresponding Source and Corresponding Application 124 | Code. If you use option 4d1, you must provide the Installation 125 | Information in the manner specified by section 6 of the GNU GPL 126 | for conveying Corresponding Source.) 127 | 128 | 5. Combined Libraries. 129 | 130 | You may place library facilities that are a work based on the 131 | Library side by side in a single library together with other library 132 | facilities that are not Applications and are not covered by this 133 | License, and convey such a combined library under terms of your 134 | choice, if you do both of the following: 135 | 136 | a) Accompany the combined library with a copy of the same work based 137 | on the Library, uncombined with any other library facilities, 138 | conveyed under the terms of this License. 139 | 140 | b) Give prominent notice with the combined library that part of it 141 | is a work based on the Library, and explaining where to find the 142 | accompanying uncombined form of the same work. 143 | 144 | 6. Revised Versions of the GNU Lesser General Public License. 145 | 146 | The Free Software Foundation may publish revised and/or new versions 147 | of the GNU Lesser General Public License from time to time. Such new 148 | versions will be similar in spirit to the present version, but may 149 | differ in detail to address new problems or concerns. 150 | 151 | Each version is given a distinguishing version number. If the 152 | Library as you received it specifies that a certain numbered version 153 | of the GNU Lesser General Public License "or any later version" 154 | applies to it, you have the option of following the terms and 155 | conditions either of that published version or of any later version 156 | published by the Free Software Foundation. If the Library as you 157 | received it does not specify a version number of the GNU Lesser 158 | General Public License, you may choose any version of the GNU Lesser 159 | General Public License ever published by the Free Software Foundation. 160 | 161 | If the Library as you received it specifies that a proxy can decide 162 | whether future versions of the GNU Lesser General Public License shall 163 | apply, that proxy's public statement of acceptance of any version is 164 | permanent authorization for you to choose that version for the 165 | Library. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Eurosentiment: Java tutorial 2 | ============================ 3 | 4 | [Eurosentiment](http://eurosentiment.eu) is a cloud marketplace that provides multilingual sentiment and emotion analysis services, pipelines for enriching language resources, and a set of standardized resources (annotated corpora and lexicons) for performing sentiment, emotion and other semantic analysis tasks. 5 | 6 | Within this repository you'll find a complete example for creating a simple sentiment analysis service using the [Eurosentiment Language Resource Pool (LRP)](https://portal.eurosentiment.eu/) based on Java language. 7 | 8 | ## Table of contents 9 | 10 | * [Creating an Eurosentiment LRP account.](https://github.com/mariomgal/eurosentiment-tutorial-java/wiki/Creating-an-Eurosentiment-LRP-account) 11 | * [Pre-requisites.](https://github.com/mariomgal/eurosentiment-tutorial-java/wiki/Pre-requisites) 12 | * [Setting up the development environment.](https://github.com/mariomgal/eurosentiment-tutorial-java/wiki/Setting-up-the-development-environment) 13 | * [Using Eurosentiment LRP services.](https://github.com/mariomgal/eurosentiment-tutorial-java/wiki/Using-Eurosentiment-LRP-services.) 14 | * [Using Eurosentiment LRP resources.](https://github.com/mariomgal/eurosentiment-tutorial-java/wiki/Using-Eurosentiment-LRP-resources.) 15 | * [Creating your first sentiment analysis application.](https://github.com/mariomgal/eurosentiment-tutorial-java/wiki/Creating-your-first-sentiment-analysis-application.) 16 | * [Exposing your application as a service.](https://github.com/mariomgal/eurosentiment-tutorial-java/wiki/Exposing-your-application-as-a-service.) 17 | * [Registering your service in Eurosentiment.](https://github.com/mariomgal/eurosentiment-tutorial-java/wiki/Registering-your-service-in-Eurosentiment.) 18 | 19 | [EUROSENTIMENT PROJECT](http://eurosentiment.eu) (Grant Agreement no: 296277, Starting date: 01/09/2012, Project duration: 24 months) 20 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | eu.eurosentiment 7 | tutorial 8 | 0.0.1-SNAPSHOT 9 | jar 10 | 11 | code-samples 12 | Eurosentiment code samples 13 | 14 | 15 | org.springframework.boot 16 | spring-boot-starter-parent 17 | 1.1.1.RELEASE 18 | 19 | 20 | 21 | 22 | 23 | org.springframework.boot 24 | spring-boot-starter-web 25 | 26 | 27 | org.springframework.boot 28 | spring-boot-starter-test 29 | test 30 | 31 | 32 | org.json 33 | json 34 | 20140107 35 | compile 36 | 37 | 38 | com.sun.jersey 39 | jersey-client 40 | 1.18.1 41 | compile 42 | 43 | 44 | 45 | 46 | UTF-8 47 | samples.Application 48 | 1.6 49 | 50 | 51 | 52 | 53 | 54 | org.springframework.boot 55 | spring-boot-maven-plugin 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /src/main/java/client/NifInput.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This program is free software: you can redistribute it and/or modify 3 | * it under the terms of the GNU Lesser General Public License as published by 4 | * the Free Software Foundation, either version 3 of the License, or 5 | * (at your option) any later version. 6 | * 7 | * This program is distributed in the hope that it will be useful, 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | * GNU Lesser General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU Lesser General Public License 13 | * along with this program. If not, see . 14 | * 15 | * 16 | * 17 | * The original code are licensed under the GNU Lesser General Public License. 18 | */ 19 | package client; 20 | 21 | import org.json.JSONObject; 22 | 23 | public class NifInput { 24 | 25 | protected JSONObject json = new JSONObject(); 26 | 27 | public NifInput(String jsonString) { 28 | if(jsonString.isEmpty()) { 29 | json = new JSONObject(); 30 | } else { 31 | json = new JSONObject(jsonString); 32 | } 33 | } 34 | 35 | public String asJson() { 36 | return json.toString(); 37 | } 38 | 39 | public String toString() { 40 | return json.toString(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/client/NifOutput.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This program is free software: you can redistribute it and/or modify 3 | * it under the terms of the GNU Lesser General Public License as published by 4 | * the Free Software Foundation, either version 3 of the License, or 5 | * (at your option) any later version. 6 | * 7 | * This program is distributed in the hope that it will be useful, 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | * GNU Lesser General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU Lesser General Public License 13 | * along with this program. If not, see . 14 | * 15 | * 16 | * 17 | * The original code are licensed under the GNU Lesser General Public License. 18 | */ 19 | package client; 20 | 21 | import org.json.JSONObject; 22 | 23 | public class NifOutput { 24 | 25 | JSONObject json; 26 | 27 | public NifOutput(String jsonString) { 28 | if(jsonString.isEmpty()) { 29 | json = new JSONObject(); 30 | } else { 31 | json = new JSONObject(jsonString); 32 | } 33 | } 34 | 35 | public JSONObject getJson() { 36 | return json; 37 | } 38 | 39 | public String toString() { 40 | return this.json.toString(); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/client/ResourceClient.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This program is free software: you can redistribute it and/or modify 3 | * it under the terms of the GNU Lesser General Public License as published by 4 | * the Free Software Foundation, either version 3 of the License, or 5 | * (at your option) any later version. 6 | * 7 | * This program is distributed in the hope that it will be useful, 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | * GNU Lesser General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU Lesser General Public License 13 | * along with this program. If not, see . 14 | * 15 | * 16 | * 17 | * The original code are licensed under the GNU Lesser General Public License. 18 | */ 19 | package client; 20 | 21 | import com.sun.jersey.api.client.Client; 22 | import com.sun.jersey.api.client.ClientResponse; 23 | import com.sun.jersey.api.client.WebResource; 24 | import org.apache.log4j.Logger; 25 | 26 | public class ResourceClient { 27 | 28 | private static final Logger log = Logger.getLogger(ResourceClient.class); 29 | 30 | private String resourceUrl; 31 | private String token; 32 | private WebResource resource; 33 | 34 | public ResourceClient(String resourceUrl, String token) { 35 | this.resourceUrl = resourceUrl; 36 | this.token = token; 37 | Client client = Client.create(); 38 | this.resource = client.resource(resourceUrl); 39 | } 40 | 41 | public NifOutput request(NifInput input) { 42 | WebResource.Builder builder = this.resource.header("x-eurosentiment-token", this.token) 43 | .header("content-type", "application/json"); 44 | log.info("Request to Resources Server at [" + resourceUrl + "] with body: " + input); 45 | ClientResponse response = builder.post(ClientResponse.class, input.asJson()); 46 | String result = response.getEntity(String.class); 47 | log.info("Response:" + result); 48 | return new NifOutput(result); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/client/ServiceClient.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This program is free software: you can redistribute it and/or modify 3 | * it under the terms of the GNU Lesser General Public License as published by 4 | * the Free Software Foundation, either version 3 of the License, or 5 | * (at your option) any later version. 6 | * 7 | * This program is distributed in the hope that it will be useful, 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | * GNU Lesser General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU Lesser General Public License 13 | * along with this program. If not, see . 14 | * 15 | * 16 | * 17 | * The original code are licensed under the GNU Lesser General Public License. 18 | */ 19 | package client; 20 | 21 | import com.sun.jersey.api.client.Client; 22 | import com.sun.jersey.api.client.ClientResponse; 23 | import com.sun.jersey.api.client.WebResource; 24 | import org.apache.log4j.Logger; 25 | 26 | public class ServiceClient { 27 | 28 | private static final Logger log = Logger.getLogger(ServiceClient.class); 29 | 30 | private String token; 31 | 32 | private WebResource resource; 33 | 34 | private String serviceUrl; 35 | 36 | public ServiceClient(String serviceUrl, String token) { 37 | this.token = token; 38 | this.serviceUrl = serviceUrl; 39 | Client client = Client.create(); 40 | if(serviceUrl != null) { 41 | this.resource = client.resource(serviceUrl); 42 | } 43 | } 44 | 45 | public NifOutput request(NifInput input) { 46 | WebResource.Builder builder = this.resource.header("x-eurosentiment-token", this.token) 47 | .header("content-type", "application/json"); 48 | log.info("Request to Services Server at [" + serviceUrl + "] with body: " + input); 49 | ClientResponse response = builder.post(ClientResponse.class, input.asJson()); 50 | String result = response.getEntity(String.class); 51 | log.info("Response:" + result); 52 | return new NifOutput(result); 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/samples/Application.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This program is free software: you can redistribute it and/or modify 3 | * it under the terms of the GNU Lesser General Public License as published by 4 | * the Free Software Foundation, either version 3 of the License, or 5 | * (at your option) any later version. 6 | * 7 | * This program is distributed in the hope that it will be useful, 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | * GNU Lesser General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU Lesser General Public License 13 | * along with this program. If not, see . 14 | * 15 | * 16 | * 17 | * The original code are licensed under the GNU Lesser General Public License. 18 | */ 19 | package samples; 20 | 21 | import org.apache.log4j.Logger; 22 | import org.springframework.boot.SpringApplication; 23 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 24 | import org.springframework.context.annotation.ComponentScan; 25 | import org.springframework.context.annotation.Configuration; 26 | 27 | 28 | @Configuration 29 | @ComponentScan({"samples", "utils"}) 30 | @EnableAutoConfiguration 31 | public class Application { 32 | 33 | private static final Logger log = Logger.getLogger(Application.class); 34 | 35 | public static void main(String[] args) { 36 | log.info("Starting EUROSENTIMENT samples application."); 37 | SpringApplication.run(Application.class, args); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/samples/NegativeWordsMatcher.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This program is free software: you can redistribute it and/or modify 3 | * it under the terms of the GNU Lesser General Public License as published by 4 | * the Free Software Foundation, either version 3 of the License, or 5 | * (at your option) any later version. 6 | * 7 | * This program is distributed in the hope that it will be useful, 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | * GNU Lesser General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU Lesser General Public License 13 | * along with this program. If not, see . 14 | * 15 | * 16 | * 17 | * The original code are licensed under the GNU Lesser General Public License. 18 | */ 19 | package samples; 20 | 21 | import client.NifInput; 22 | import client.NifOutput; 23 | import client.ResourceClient; 24 | import client.ServiceClient; 25 | import org.apache.log4j.Logger; 26 | import org.springframework.stereotype.Component; 27 | 28 | import javax.annotation.PostConstruct; 29 | import java.util.List; 30 | import java.util.Map; 31 | import java.util.Set; 32 | 33 | @Component 34 | public class NegativeWordsMatcher extends WordsMatcher { 35 | 36 | private static final Logger log = Logger.getLogger(NegativeWordsMatcher.class); 37 | 38 | public Map getNegativeWords(String text) { 39 | NifOutput languageResult = this.languageDetector.request(new NifInput("{'text':'" + text + "'}")); 40 | String language = languageResult.getJson().getString("dc:language"); 41 | log.info("The detected language is [" + language + "]"); 42 | NifOutput domainResult = this.domainDetector.request(new NifInput("{'text':'" + text + "'}")); 43 | String domain = domainResult.getJson().getString("domain"); 44 | String domainName = domain.split(":")[1]; 45 | log.info("The detected domain is [" + domainName + "]"); 46 | String query = SparqlQueryFactory.getSparql(SparqlQueryFactory.NEGATIVE_ENTRIES, language, domainName); 47 | NifInput input = new NifInput("{'query':'" + query + "', " + 48 | "'format':'application/json'}"); 49 | NifOutput wordsResults = this.resourceClient.request(input); 50 | Set sentimentWords = extractWordsListFromResponse(wordsResults.getJson()); 51 | log.info(sentimentWords.size() + " positive words retrieved."); 52 | return matchWords(text, sentimentWords); 53 | } 54 | 55 | @PostConstruct 56 | public void initialized() throws Exception { 57 | this.languageDetector = new ServiceClient(this.languageDetectionServiceUrl, this.token); 58 | this.domainDetector = new ServiceClient(this.domainDetectionServiceUrl, this.token); 59 | this.resourceClient = new ResourceClient(this.resourcesUrl, this.token); 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/samples/PositiveWordsMatcher.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This program is free software: you can redistribute it and/or modify 3 | * it under the terms of the GNU Lesser General Public License as published by 4 | * the Free Software Foundation, either version 3 of the License, or 5 | * (at your option) any later version. 6 | * 7 | * This program is distributed in the hope that it will be useful, 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | * GNU Lesser General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU Lesser General Public License 13 | * along with this program. If not, see . 14 | * 15 | * 16 | * 17 | * The original code are licensed under the GNU Lesser General Public License. 18 | */ 19 | package samples; 20 | 21 | import client.NifInput; 22 | import client.NifOutput; 23 | import client.ResourceClient; 24 | import client.ServiceClient; 25 | import org.apache.log4j.Logger; 26 | import org.springframework.stereotype.Component; 27 | 28 | import javax.annotation.PostConstruct; 29 | import java.util.List; 30 | import java.util.Map; 31 | import java.util.Set; 32 | 33 | @Component 34 | public class PositiveWordsMatcher extends WordsMatcher { 35 | 36 | private static final Logger log = Logger.getLogger(PositiveWordsMatcher.class); 37 | 38 | public Map getPositiveWords(String text) { 39 | NifOutput languageResult = this.languageDetector.request(new NifInput("{'text':'" + text + "'}")); 40 | String language = languageResult.getJson().getString("dc:language"); 41 | log.info("The detected language is [" + language + "]"); 42 | NifOutput domainResult = this.domainDetector.request(new NifInput("{'text':'" + text + "'}")); 43 | String domain = domainResult.getJson().getString("domain"); 44 | String domainName = domain.split(":")[1]; 45 | log.info("The detected domain is [" + domainName + "]"); 46 | String query = SparqlQueryFactory.getSparql(SparqlQueryFactory.POSITIVE_ENTRIES, language, domainName); 47 | NifInput input = new NifInput("{'query':'" + query + "', " + 48 | "'format':'application/json'}"); 49 | NifOutput wordsResults = this.resourceClient.request(input); 50 | Set sentimentWords = extractWordsListFromResponse(wordsResults.getJson()); 51 | log.info(sentimentWords.size() + " positive words retrieved."); 52 | return matchWords(text, sentimentWords); 53 | } 54 | 55 | @PostConstruct 56 | public void initClients() { 57 | this.languageDetector = new ServiceClient(this.languageDetectionServiceUrl, this.token); 58 | this.domainDetector = new ServiceClient(this.domainDetectionServiceUrl, this.token); 59 | this.resourceClient = new ResourceClient(this.resourcesUrl, this.token); 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/samples/Server.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This program is free software: you can redistribute it and/or modify 3 | * it under the terms of the GNU Lesser General Public License as published by 4 | * the Free Software Foundation, either version 3 of the License, or 5 | * (at your option) any later version. 6 | * 7 | * This program is distributed in the hope that it will be useful, 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | * GNU Lesser General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU Lesser General Public License 13 | * along with this program. If not, see . 14 | * 15 | * 16 | * 17 | * The original code are licensed under the GNU Lesser General Public License. 18 | */ 19 | package samples; 20 | 21 | import java.util.concurrent.atomic.AtomicLong; 22 | 23 | import org.json.JSONObject; 24 | import org.springframework.beans.factory.annotation.Autowired; 25 | import org.springframework.stereotype.Controller; 26 | import org.springframework.web.bind.annotation.*; 27 | 28 | import javax.ws.rs.WebApplicationException; 29 | 30 | @RestController 31 | public class Server { 32 | 33 | @Autowired 34 | SimpleSentimentAnalyzer analyzer; 35 | 36 | @RequestMapping(value = "/sentiment", 37 | method = RequestMethod.POST, 38 | produces = {"application/json"}) 39 | public String getSentiment(@RequestBody String input) throws Exception { 40 | try { 41 | JSONObject jsonInput = new JSONObject(input); 42 | return analyzer.getSentiment(jsonInput.getString("input")).toString(); 43 | } catch(Exception e) { 44 | throw e; 45 | } 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/samples/SimpleSentimentAnalyzer.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This program is free software: you can redistribute it and/or modify 3 | * it under the terms of the GNU Lesser General Public License as published by 4 | * the Free Software Foundation, either version 3 of the License, or 5 | * (at your option) any later version. 6 | * 7 | * This program is distributed in the hope that it will be useful, 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | * GNU Lesser General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU Lesser General Public License 13 | * along with this program. If not, see . 14 | * 15 | * 16 | * 17 | * The original code are licensed under the GNU Lesser General Public License. 18 | */ 19 | package samples; 20 | 21 | import client.NifOutput; 22 | import org.apache.log4j.Logger; 23 | import org.json.JSONObject; 24 | import org.springframework.beans.factory.annotation.Autowired; 25 | import org.springframework.context.annotation.Bean; 26 | import org.springframework.stereotype.Component; 27 | 28 | import java.util.Map; 29 | 30 | @Component 31 | public class SimpleSentimentAnalyzer { 32 | 33 | private static final Logger log = Logger.getLogger(SimpleSentimentAnalyzer.class); 34 | 35 | @Autowired 36 | private PositiveWordsMatcher positiveWordsMatcher; 37 | 38 | @Autowired 39 | private NegativeWordsMatcher negativeWordsMatcher; 40 | 41 | public NifOutput getSentiment(String text) { 42 | log.info("Retrieving negative matches..."); 43 | Map negativeWords = negativeWordsMatcher.getNegativeWords(text); 44 | log.info("Retrieving positive matches..."); 45 | Map positiveWords = positiveWordsMatcher.getPositiveWords(text); 46 | double sentiment = calculateSentiment(positiveWords, negativeWords); 47 | return new NifOutput("{\"@context\": \"http://eurosentiment.eu/contexts/basecontext.jsonld\"," + 48 | "\"@type\":\"marl:SentimentAnalysis\"," + 49 | "\"marl:polarityValue\":" + sentiment +"}"); 50 | 51 | } 52 | 53 | private double calculateSentiment(Map positiveWords, Map negativeWords) { 54 | int positiveCount = sumMapValues(positiveWords); 55 | log.info("Number of positive words:" + positiveCount); 56 | int negativeCount = sumMapValues(negativeWords); 57 | log.info("Number of negative words:" + negativeCount); 58 | if ((positiveCount + negativeCount) > 0) { 59 | return ((double)(positiveCount-negativeCount))/(positiveCount + negativeCount); 60 | } 61 | return 0.0d; 62 | } 63 | 64 | private int sumMapValues(Map words) { 65 | int result = 0; 66 | for(Integer count:words.values()) { 67 | result += count; 68 | } 69 | return result; 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/samples/SparqlQuery.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This program is free software: you can redistribute it and/or modify 3 | * it under the terms of the GNU Lesser General Public License as published by 4 | * the Free Software Foundation, either version 3 of the License, or 5 | * (at your option) any later version. 6 | * 7 | * This program is distributed in the hope that it will be useful, 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | * GNU Lesser General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU Lesser General Public License 13 | * along with this program. If not, see . 14 | * 15 | * 16 | * 17 | * The original code are licensed under the GNU Lesser General Public License. 18 | */ 19 | package samples; 20 | 21 | import java.util.HashMap; 22 | import java.util.Map; 23 | 24 | public class SparqlQuery { 25 | 26 | public class Language { 27 | 28 | public static final String ENGLISH = "en"; 29 | 30 | public static final String SPANISH = "es"; 31 | 32 | } 33 | 34 | public class Domain { 35 | 36 | public static final String ELECTRONICS = "electronics"; 37 | 38 | public static final String HOTEL = "hotel"; 39 | } 40 | 41 | private String language; 42 | 43 | private String domain; 44 | 45 | private String prefix; 46 | 47 | private String query; 48 | 49 | private Map> prefixesDictionary; 50 | 51 | public SparqlQuery(String query) { 52 | this.language = ""; 53 | this.domain = ""; 54 | this.query = query; 55 | this.prefixesDictionary = new HashMap>(); 56 | Map prefixByDomainES = new HashMap(); 57 | Map prefixByDomainEN = new HashMap(); 58 | prefixByDomainEN.put(Domain.ELECTRONICS, "gabvul/2"); 59 | prefixByDomainES.put(Domain.ELECTRONICS, "gabvul/3"); 60 | prefixByDomainEN.put(Domain.HOTEL, "gabvul/8"); 61 | prefixByDomainES.put(Domain.HOTEL, "gabvul/9"); 62 | prefixesDictionary.put(Language.ENGLISH, prefixByDomainEN); 63 | prefixesDictionary.put(Language.SPANISH, prefixByDomainES); 64 | } 65 | 66 | public SparqlQuery(String prefix, String query) { 67 | this.language = ""; 68 | this.domain = ""; 69 | this.query = ""; 70 | this.prefix = prefix; 71 | } 72 | 73 | public String getGraphUri(String language, String domain) { 74 | this.language = language; 75 | this.domain = domain; 76 | return this.getGraphUri(); 77 | } 78 | 79 | public String getPrefix() { 80 | if (!this.isValid()) { 81 | throw new IllegalStateException("SparQL query must have not empty domain or language"); 82 | } 83 | if(prefix != null) { 84 | return prefix; 85 | } 86 | return prefixesDictionary.get(this.language).get(this.domain); 87 | } 88 | 89 | public String getSuffix() { 90 | return "lexicon"; 91 | } 92 | 93 | public String getGraphUri() { 94 | if (!this.isValid()) { 95 | throw new IllegalStateException("SparQL query must have not empty domain or language"); 96 | } 97 | return new StringBuilder().append("http://www.eurosentiment.eu/dataset/").append(domain). 98 | append("/").append(language).append("/").append(getPrefix()).append("/"). 99 | append(getSuffix()).toString(); 100 | } 101 | 102 | public String getSparql(String language, String domain) { 103 | return String.format(this.query, this.getGraphUri(language, domain)); 104 | } 105 | 106 | private boolean isValid() { 107 | return !this.language.isEmpty() && !this.domain.isEmpty(); 108 | } 109 | 110 | 111 | } 112 | -------------------------------------------------------------------------------- /src/main/java/samples/SparqlQueryFactory.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This program is free software: you can redistribute it and/or modify 3 | * it under the terms of the GNU Lesser General Public License as published by 4 | * the Free Software Foundation, either version 3 of the License, or 5 | * (at your option) any later version. 6 | * 7 | * This program is distributed in the hope that it will be useful, 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | * GNU Lesser General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU Lesser General Public License 13 | * along with this program. If not, see . 14 | * 15 | * 16 | * 17 | * The original code are licensed under the GNU Lesser General Public License. 18 | */ 19 | package samples; 20 | 21 | public class SparqlQueryFactory { 22 | 23 | 24 | 25 | public static final SparqlQuery POSITIVE_ENTRIES = new SparqlQuery("PREFIX lemon: PREFIX marl: SELECT DISTINCT ?wordWithSentiment ?polarityValue ?sentimentEntry ?sentimentEntryWR from <%s> where { ?sentimentEntry lemon:sense ?sense . ?sentimentEntry lemon:canonicalForm ?secf . ?secf lemon:writtenRep ?sentimentEntryWR . ?sense marl:polarityValue ?polarityValue . ?sense marl:hasPolarity . ?sense lemon:reference ?reference . ?sense lemon:context ?context . ?entryWithSentiment lemon:sense ?context . ?entryWithSentiment lemon:canonicalForm ?cf . ?cf lemon:writtenRep ?wordWithSentiment . }"); 26 | 27 | public static final SparqlQuery NEGATIVE_ENTRIES = new SparqlQuery("PREFIX lemon: PREFIX marl: SELECT DISTINCT ?wordWithSentiment ?polarityValue ?sentimentEntry ?sentimentEntryWR from <%s> where { ?sentimentEntry lemon:sense ?sense . ?sentimentEntry lemon:canonicalForm ?secf . ?secf lemon:writtenRep ?sentimentEntryWR . ?sense marl:polarityValue ?polarityValue . ?sense marl:hasPolarity . ?sense lemon:reference ?reference . ?sense lemon:context ?context . ?entryWithSentiment lemon:sense ?context . ?entryWithSentiment lemon:canonicalForm ?cf . ?cf lemon:writtenRep ?wordWithSentiment . }"); 28 | 29 | public static String getSparql(SparqlQuery query, String language, String domain) { 30 | return query.getSparql(language, domain); 31 | } 32 | 33 | } -------------------------------------------------------------------------------- /src/main/java/samples/WordsMatcher.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This program is free software: you can redistribute it and/or modify 3 | * it under the terms of the GNU Lesser General Public License as published by 4 | * the Free Software Foundation, either version 3 of the License, or 5 | * (at your option) any later version. 6 | * 7 | * This program is distributed in the hope that it will be useful, 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | * GNU Lesser General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU Lesser General Public License 13 | * along with this program. If not, see . 14 | * 15 | * 16 | * 17 | * The original code are licensed under the GNU Lesser General Public License. 18 | */ 19 | package samples; 20 | 21 | import client.ResourceClient; 22 | import client.ServiceClient; 23 | import org.json.JSONArray; 24 | import org.json.JSONObject; 25 | import org.springframework.beans.factory.annotation.Autowired; 26 | import org.springframework.beans.factory.annotation.Value; 27 | import org.springframework.stereotype.Component; 28 | import utils.TextMatcher; 29 | 30 | import java.util.*; 31 | 32 | @Component 33 | public abstract class WordsMatcher { 34 | 35 | @Value("${eurosentiment.language.detection.url}") 36 | protected String languageDetectionServiceUrl; 37 | 38 | @Value("${eurosentiment.domain.detection.url}") 39 | protected String domainDetectionServiceUrl; 40 | 41 | @Value("${eurosentiment.resources.url}") 42 | protected String resourcesUrl; 43 | 44 | @Value("${eurosentiment.token}") 45 | protected String token; 46 | 47 | protected ServiceClient languageDetector; 48 | 49 | protected ServiceClient domainDetector; 50 | 51 | protected ResourceClient resourceClient; 52 | 53 | @Autowired 54 | private TextMatcher textMatcher; 55 | 56 | protected Set extractWordsListFromResponse(JSONObject wordsResults) { 57 | Set result = new HashSet(); 58 | JSONArray bindings = wordsResults.getJSONObject("results").getJSONArray("bindings"); 59 | for(int i=0; i matchWords(String text, Collection words) { 67 | return textMatcher.matchesInText(text, words); 68 | } 69 | 70 | 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/utils/TextMatcher.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This program is free software: you can redistribute it and/or modify 3 | * it under the terms of the GNU Lesser General Public License as published by 4 | * the Free Software Foundation, either version 3 of the License, or 5 | * (at your option) any later version. 6 | * 7 | * This program is distributed in the hope that it will be useful, 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | * GNU Lesser General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU Lesser General Public License 13 | * along with this program. If not, see . 14 | * 15 | * 16 | * 17 | * The original code are licensed under the GNU Lesser General Public License. 18 | */ 19 | package utils; 20 | 21 | import org.springframework.beans.factory.annotation.Autowired; 22 | import org.springframework.stereotype.Component; 23 | 24 | import java.util.*; 25 | 26 | @Component 27 | public class TextMatcher { 28 | 29 | @Autowired 30 | private TextNormalizer normalizer; 31 | 32 | public Map matchesInText(String text, Collection words) { 33 | Map results = new HashMap(); 34 | String normalizedText = normalizer.normalizeText(text); 35 | List tokenizedText = Arrays.asList(normalizedText.split("\\s+")); 36 | for(String word:words) { 37 | String normalizedWord = normalizer.normalizeText(word); 38 | int frequency = Collections.frequency(tokenizedText, normalizedWord); 39 | if(frequency > 0) { 40 | results.put(word, frequency); 41 | } 42 | } 43 | return results; 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/utils/TextNormalizer.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This program is free software: you can redistribute it and/or modify 3 | * it under the terms of the GNU Lesser General Public License as published by 4 | * the Free Software Foundation, either version 3 of the License, or 5 | * (at your option) any later version. 6 | * 7 | * This program is distributed in the hope that it will be useful, 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | * GNU Lesser General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU Lesser General Public License 13 | * along with this program. If not, see . 14 | * 15 | * 16 | * 17 | * The original code are licensed under the GNU Lesser General Public License. 18 | */ 19 | package utils; 20 | 21 | import org.springframework.stereotype.Component; 22 | 23 | import java.text.Normalizer; 24 | 25 | @Component 26 | public class TextNormalizer { 27 | 28 | public String normalizeText(String text) { 29 | return text == null ? null 30 | : Normalizer.normalize(text, Normalizer.Form.NFD) 31 | .replaceAll("\\p{InCombiningDiacriticalMarks}+", "").toLowerCase(); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | server.port=8090 2 | 3 | eurosentiment.token=INSERT_YOUR_TOKEN_HERE 4 | 5 | eurosentiment.language.detection.url=http://217.26.90.243:8080/EuroSentimentServices/services/server/access/sptdl0407 6 | eurosentiment.domain.detection.url=http://217.26.90.243:8080/EuroSentimentServices/services/server/access/710e9337-7024-4205-a8f4-376724b867f7 7 | eurosentiment.resources.url=http://54.201.101.125/sparql/ 8 | -------------------------------------------------------------------------------- /src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/test/java/client/ServiceClientTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This program is free software: you can redistribute it and/or modify 3 | * it under the terms of the GNU Lesser General Public License as published by 4 | * the Free Software Foundation, either version 3 of the License, or 5 | * (at your option) any later version. 6 | * 7 | * This program is distributed in the hope that it will be useful, 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | * GNU Lesser General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU Lesser General Public License 13 | * along with this program. If not, see . 14 | * 15 | * 16 | * 17 | * The original code are licensed under the GNU Lesser General Public License. 18 | */ 19 | package client; 20 | 21 | import org.junit.Test; 22 | import static org.junit.Assert.*; 23 | 24 | public class ServiceClientTest { 25 | 26 | private String token = "78cab860-d17d-4afa-b1ac-d6ff84e942d7"; 27 | 28 | private String serviceUrl = "http://217.26.90.243:8080/EuroSentimentServices/services/server/accessNoToken/sesld1129"; 29 | 30 | @Test 31 | public void testServiceClient() { 32 | ServiceClient client = new ServiceClient(serviceUrl, token); 33 | NifInput input = new NifInput("{'input': 'El resultado debería ser castellano'}"); 34 | NifOutput output = client.request(input); 35 | assertEquals(output.getJson().getJSONArray("entries").getJSONObject(0).get("dc:language"), 36 | "Spanish"); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/test/java/samples/ApplicationTests.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This program is free software: you can redistribute it and/or modify 3 | * it under the terms of the GNU Lesser General Public License as published by 4 | * the Free Software Foundation, either version 3 of the License, or 5 | * (at your option) any later version. 6 | * 7 | * This program is distributed in the hope that it will be useful, 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | * GNU Lesser General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU Lesser General Public License 13 | * along with this program. If not, see . 14 | * 15 | * 16 | * 17 | * The original code are licensed under the GNU Lesser General Public License. 18 | */ 19 | package samples; 20 | 21 | import org.junit.Test; 22 | import org.junit.runner.RunWith; 23 | import org.springframework.boot.test.SpringApplicationConfiguration; 24 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 25 | 26 | @RunWith(SpringJUnit4ClassRunner.class) 27 | @SpringApplicationConfiguration(classes = Server.class) 28 | public class ApplicationTests { 29 | 30 | @Test 31 | public void contextLoads() { 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/test/resources/test.properties: -------------------------------------------------------------------------------- 1 | eurosentiment.token=YOUR_EUROSENTIMENT_TOKEN_HERE 2 | 3 | eurosentiment.language.detection.url=http://54.187.254.3/services/language_detector 4 | eurosentiment.resources.url=http://54.201.101.125/sparql/ --------------------------------------------------------------------------------