/** * <a href="http://www.openolat.org"> * OpenOLAT - Online Learning and Training</a><br> * <p> * Licensed under the Apache License, Version 2.0 (the "License"); <br> * you may not use this file except in compliance with the License.<br> * You may obtain a copy of the License at the * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> * <p> * Unless required by applicable law or agreed to in writing,<br> * software distributed under the License is distributed on an "AS IS" BASIS, <br> * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> * See the License for the specific language governing permissions and <br> * limitations under the License. * <p> * Initial code contributed and copyrighted by<br> * frentix GmbH, http://www.frentix.com * <p> */ package org.olat.core.commons.modules.glossary.morphService; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import org.apache.http.Header; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.NameValuePair; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.utils.URIBuilder; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.message.BasicNameValuePair; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; import org.olat.core.util.httpclient.HttpClientFactory; import org.olat.core.util.xml.XStreamHelper; import com.thoughtworks.xstream.XStream; /** * Description:<br> * Connects to a morphological service and lets retrieve flexions for a word. * This is a variant to be used with german glossaries and is only compatible * with the defined service. * * <P> * Initial Date: 09.12.2008 <br> * * @author Roman Haag, frentix GmbH, roman.haag@frentix.com */ public class MorphologicalServiceDEImpl implements MorphologicalService { private static final String MORPHOLOGICAL_SERVICE_ADRESS = "http://www.cl.uzh.ch/kitt/cgi-bin/olat/ms_de.cgi"; private static final String SERVICE_NAME = "Morphological Service DE - University Zurich"; private static final String SERVICE_IDENTIFIER = "ms-de-uzh-cli"; private static final String PART_OF_SPEECH_PARAM = "pos"; private static final String GLOSS_TERM_PARAM = "word"; private static OLog log = Tracing.createLoggerFor(MorphologicalServiceDEImpl.class); private String replyStatus = ""; /** * */ public MorphologicalServiceDEImpl() { // } /** * * @see org.olat.core.commons.modules.glossary.morphService.FlexionServiceClient#getFlexions(java.lang.String) */ @Override public List<String> getFlexions(String word) { return getFlexions(assumePartOfSpeech(word), word); } /** * * @see org.olat.core.commons.modules.glossary.morphService.FlexionServiceClient#getFlexions(java.lang.String, * java.lang.String) */ @Override public List<String> getFlexions(String partOfSpeech, String word) { InputStream xmlReplyStream = retreiveXMLReply(partOfSpeech, word); XStream xstream = XStreamHelper.createXStreamInstance(); xstream.alias("xml", FlexionReply.class); xstream.alias("wordform", String.class); ArrayList<String> stemWithWordforms; try { Object msReply = XStreamHelper.readObject(xstream, xmlReplyStream); FlexionReply flexionReply = (FlexionReply) msReply; // set reply status to remind it setReplyStatus(flexionReply.getStatus()); stemWithWordforms = flexionReply.getStem(); } catch (Exception e) { log.error("XML-Reply was not valid XML", e); stemWithWordforms = null; setReplyStatus(MorphologicalService.STATUS_ERROR); } return stemWithWordforms; } /** * Remind: this assumptions are only valuable for german language! * * @see org.olat.core.commons.modules.glossary.morphService.FlexionServiceClient#assumePartOfSpeech(java.lang.String) */ @Override public String assumePartOfSpeech(String glossTerm) { if (glossTerm.contains(",")) { // assume the form "House, beautiful" return "an"; } // look if glossTerm consists of more than 1 word -> adjective + noun String firstChar = glossTerm.substring(0, 1); if (glossTerm.split(" ").length > 1 && firstChar.equals(firstChar.toLowerCase())) return "an"; //single or multiple word with big initial -> noun(s) if (firstChar.equals(firstChar.toUpperCase())) return "n"; return "v"; } private InputStream retreiveXMLReply(String partOfSpeech, String word) { try { URIBuilder uriBuilder = new URIBuilder(MORPHOLOGICAL_SERVICE_ADRESS); List<NameValuePair> nvps = new ArrayList<NameValuePair>(2); nvps.add(new BasicNameValuePair(PART_OF_SPEECH_PARAM, partOfSpeech)); nvps.add(new BasicNameValuePair(GLOSS_TERM_PARAM, word)); CloseableHttpClient client = HttpClientFactory.getHttpClientInstance(true); HttpGet method = new HttpGet(uriBuilder.build()); HttpResponse response = client.execute(method); int status = response.getStatusLine().getStatusCode(); if (status == HttpStatus.SC_NOT_MODIFIED || status == HttpStatus.SC_OK) { if (log.isDebug()) { log.debug("got a valid reply!"); } } else if (status == HttpStatus.SC_NOT_FOUND) { log.error("Morphological Service unavailable (404)::" + response.getStatusLine().toString()); } else { log.error("Unexpected HTTP Status::" + response.getStatusLine().toString()); } Header responseHeader = response.getFirstHeader("Content-Type"); if (responseHeader == null) { // error log.error("URL not found!"); } return response.getEntity().getContent(); } catch (Exception e) { log.error("Unexpected exception trying to get flexions!", e); return null; } } /** * * @see org.olat.core.commons.modules.glossary.morphService.FlexionServiceClient#getReplyStatus() */ public String getReplyStatus() { return replyStatus; } /** * sets the status found in the reply * * @param replyStatus */ private void setReplyStatus(String replyStatus) { this.replyStatus = replyStatus; } /** * * @see org.olat.core.commons.modules.glossary.morphService.FlexionServiceManager#getFlexionServiceDescriptor() */ public String getMorphServiceDescriptor() { return SERVICE_NAME; } /** * * @see org.olat.core.commons.modules.glossary.morphService.FlexionServiceManager#getFlexionServiceIdentifier() */ public String getMorphServiceIdentifier() { return SERVICE_IDENTIFIER; } // private String inputStreamToString(InputStream in) throws IOException { // BufferedReader bufferedReader = new BufferedReader(new // InputStreamReader(in)); // StringBuilder stringBuilder = new StringBuilder(); // String line = null; // // while ((line = bufferedReader.readLine()) != null) { // stringBuilder.append(line + "\n"); // } // // bufferedReader.close(); // return stringBuilder.toString(); // } }