Java tutorial
/* * @cond LICENSE * ###################################################################################### * # LGPL License # * # # * # This file is part of the LightJason AgentSpeak(L++) # * # Copyright (c) 2015-17, LightJason (info@lightjason.org) # * # This program is free software: you can redistribute it and/or modify # * # it under the terms of the GNU Lesser General Public License as # * # published by the Free Software Foundation, either version 3 of the # * # License, or (at your option) any later version. # * # # * # This program is distributed in the hope that it will be useful, # * # but WITHOUT ANY WARRANTY; without even the implied warranty of # * # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # * # GNU Lesser General Public License for more details. # * # # * # You should have received a copy of the GNU Lesser General Public License # * # along with this program. If not, see http://www.gnu.org/licenses/ # * ###################################################################################### * @endcond */ package org.lightjason.agentspeak.action.builtin.rest; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.dataformat.xml.XmlMapper; import com.google.common.base.Charsets; import com.google.common.io.CharStreams; import com.google.common.io.Closeables; import org.lightjason.agentspeak.action.builtin.IBuiltinAction; import org.lightjason.agentspeak.common.CCommon; import org.lightjason.agentspeak.language.CLiteral; import org.lightjason.agentspeak.language.CRawTerm; import org.lightjason.agentspeak.language.ILiteral; import org.lightjason.agentspeak.language.ITerm; import javax.annotation.Nonnegative; import javax.annotation.Nonnull; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import java.nio.charset.Charset; import java.util.Collection; import java.util.Map; import java.util.Stack; import java.util.stream.Collectors; import java.util.stream.Stream; /** * base class to read data from the restful service * * @note all action which inherits this class uses the system property "http.agent" for defining * the http user-agent */ public abstract class IBaseRest extends IBuiltinAction { /** * serial id */ private static final long serialVersionUID = -3713528201539676487L; @Nonnegative @Override public final int minimalArgumentNumber() { return 2; } /** * reads a json structure from an url * * @param p_url url * @param p_class convert class type * @return data object * * @throws IOException is thrown on io errors */ @Nonnull protected static <T> T json(@Nonnull final String p_url, @Nonnull final Class<T> p_class) throws IOException { return new ObjectMapper().readValue(IBaseRest.httpdata(p_url), p_class); } /** * reads a xml structure from an url * * @param p_url url * @return map with xml data * * @throws IOException is thrown on io errors */ @Nonnull @SuppressWarnings("unchecked") protected static Map<String, ?> xml(@Nonnull final String p_url) throws IOException { return new XmlMapper().readValue(IBaseRest.httpdata(p_url), Map.class); } /** * creates a literal structure from a stream of string elements, * the string stream will be build in a tree structure * * @param p_functor stream with functor strings * @param p_values value stream * @return term */ @Nonnull protected static ITerm baseliteral(@Nonnull final Stream<String> p_functor, @Nonnull final Stream<ITerm> p_values) { final Stack<String> l_tree = p_functor.collect(Collectors.toCollection(Stack::new)); ILiteral l_literal = CLiteral.from(l_tree.pop(), p_values); while (!l_tree.isEmpty()) l_literal = CLiteral.from(l_tree.pop(), l_literal); return l_literal; } /** * converts an object into a term stream * * @param p_object object * @return term stream */ @Nonnull @SuppressWarnings("unchecked") protected static Stream<ITerm> flatterm(@Nonnull final Object p_object) { return p_object instanceof Map ? flatmap((Map<String, ?>) p_object) : p_object instanceof Collection ? flatcollection((Collection) p_object) : Stream.of(CRawTerm.from(p_object)); } /** * creates a HTTP connection and reads the data * * @param p_url url * @return url data * * @throws IOException is thrown on connection errors */ @Nonnull private static String httpdata(@Nonnull final String p_url) throws IOException { final HttpURLConnection l_connection = (HttpURLConnection) new URL(p_url).openConnection(); // follow HTTP redirects l_connection.setInstanceFollowRedirects(true); // set a HTTP-User-Agent if not exists l_connection.setRequestProperty("User-Agent", (System.getProperty("http.agent") == null) || (System.getProperty("http.agent").isEmpty()) ? CCommon.PACKAGEROOT + CCommon.configuration().getString("version") : System.getProperty("http.agent")); // read stream data final InputStream l_stream = l_connection.getInputStream(); final String l_return = CharStreams.toString(new InputStreamReader(l_stream, (l_connection.getContentEncoding() == null) || (l_connection.getContentEncoding().isEmpty()) ? Charsets.UTF_8 : Charset.forName(l_connection.getContentEncoding()))); Closeables.closeQuietly(l_stream); return l_return; } /** * transformas a map into a literal * * @param p_map input map * @return term stream */ @Nonnull private static Stream<ITerm> flatmap(@Nonnull final Map<String, ?> p_map) { return p_map.entrySet().stream().map(i -> CLiteral .from(i.getKey().toLowerCase().replaceAll("[^([a-z][0-9]\\-/_)]]", "_"), flatterm(i.getValue()))); } /** * transforms a collection into a term stream * * @param p_collection collection * @return term stream */ @Nonnull private static Stream<ITerm> flatcollection(@Nonnull final Collection<?> p_collection) { return p_collection.stream().flatMap(IBaseRest::flatterm); } }