I am trying to pass Java class as parameter in function, reason behind it it that I have several pojo classes for different APIs and I am trying to create a single parser utility for all the API URL and pojo class, I have tried with little or no success.
below is the code example -
public class util {
public static void main(String[] args) throws JsonParseException, JsonMappingException, IOException {
List<JsonGenMovies> jsongen = null;
String url = "http://www.dishanywhere.com/radish/v20/dol/movies/carousels/featured.json?nkey=0e1345ee597cf280c8a2cde367b6b894";
getMovieParser(jsongen, url);
List<JsonGenShow> jsongenShow = null;
String URL = "http://www.dishanywhere.com/radish/v20/dol/shows/carousels/featured.json";
getShowParser(jsongenShow, URL);
}
public static String[] getMovieParser (List<JsonGenMovies> jsongen, String url ) throws JsonParseException, JsonMappingException, IOException
{
URL jsonUrl = new URL(url);
ObjectMapper objmapper = new ObjectMapper();
jsongen = objmapper.readValue(jsonUrl, new TypeReference<List<JsonGenMovies>>() {});
String[] shows = new String [jsongen.size()];
int i = 0;
for(JsonGenMovies element : jsongen) {
shows[i++]=element.getName();
}
for(int j =0; j<shows.length;j++)
{
System.out.println(shows[j]);
}
return shows;
}
public static String[] getShowParser (List<JsonGen> jsongenShow, String URL ) throws JsonParseException, JsonMappingException, IOException
{
URL jsonUrl = new URL(URL);
ObjectMapper objmapper = new ObjectMapper();
jsongenShow = objmapper.readValue(jsonUrl, new TypeReference<List<JsonGen>>() {});
String[] shows = new String [jsongenShow.size()];
int i = 0;
for(JsonGen element : jsongenShow) {
shows[i++]=element.getName();
}
for(int j =0; j<shows.length;j++)
{
System.out.println(shows[j]);
}
return shows;
}
}
in the line -
jsongen = objmapper.readValue(jsonUrl, new TypeReference<List<JsonGen>>() {});
I still have <List<JsonGen>>a hard coded class name which I am trying to replace with arguments. please if you can help.
Please reply with little explanation, one liner might not be my thing.
Regards
Shek
If i understand correctly you want to have one function instead of two or more.
You can do that with generic type
E.g
public static <T> String[] getParser(List<T> jsongen, String url) throws JsonParseException, JsonMappingException, IOException {
URL jsonUrl = new URL(url);
ObjectMapper objmapper = new ObjectMapper();
jsongen = objmapper.readValue(jsonUrl, new TypeReference<List<T>>() {
});
String[] shows = new String[jsongen.size()];
int i = 0;
for (T element : jsongen) {
shows[i++] = element.getName();
}
for (int j = 0; j < shows.length; j++) {
System.out.println(shows[j]);
}
return shows;
}
If both JsonGenMovies and JsonGen extends/implements an interface or class, E.g JsonGenMovies extends Json then you can do this :
public static <T extends Json> String[] getParser(List<T> jsongen, String url)
T is a generic type, it does not really exist but it will be replaced at runtime by Class used for jsongen arg.
For example in :
List<String> myList;
getParser(myList, "http://blablabla.blalb.com");
All T are replaced by String.
I hope this is what you are looking for.
you can found more explanation about generic type here with better explanation than mine.
EDIT:
If you want to keep your POJO pattern then you can try this (not sure it will works)
public static String[] getParser(List<?> jsongen, String url) throws Exception {
URL jsonUrl = new URL(url);
ObjectMapper objmapper = new ObjectMapper();
jsongen = objmapper.readValue(jsonUrl, new TypeReference<List<?>>() {
});
String[] shows = new String[jsongen.size()];
int i = 0;
for (Object element : jsongen) {
Method method = element.getClass().getMethod("getName");
shows[i++] = (String) method.invoke(element);
}
for (int j = 0; j < shows.length; j++) {
System.out.println(shows[j]);
}
return shows;
}
Related
I getting confused with how to get duration, time and distance traveled using google distancematrix.api I can't understand whats not working with my code, all that I'm getting are null values. why ?? Below is my javacode
DistanceMatrix results1 = DistanceMatrixApi.getDistanceMatrix(context,
new String[] {"rose hill"}, new String[] {"port louis"}).units(Unit.METRIC).await();
System.out.println(results1.rows[0].elements[0].duration);
System.out.println(results1.rows[0].elements[0].distance);
System.out.println(results1.rows[0].elements[0].distance);
context as requested
GeoApiContext context = new GeoApiContext.Builder()
.apiKey("AIzaSyC..")
.build();
It worked for me just by creating (and enabling) an API key on the google maps
Here is my code
public class GoogleDistance {
public static void main(String[] args) throws InterruptedException, ApiException, IOException {
new GoogleDistance().go();
}
void go() throws InterruptedException, ApiException, IOException {
String API_KEY = "AIzy....";
GeoApiContext.Builder builder = new GeoApiContext.Builder();
builder.apiKey(API_KEY);
GeoApiContext geoApiContext = builder.build();
DistanceMatrix results1 = DistanceMatrixApi.getDistanceMatrix(geoApiContext,
new String[]{"rose hill"}, new String[]{"port louis"}).units(Unit.METRIC).await();
System.out.println(Arrays.toString(results1.destinationAddresses));
}
}
I believe the issue may be with your prints: I don't think you should be doing rows[0].elements[0] just use Arrays.toString().
When I run my code it outputs [Port Louis, Mauritius]
EDIT
I think I now see what you were trying to do. Please take a look at the following
public class GoogleDistance {
public static void main(String[] args) throws InterruptedException, ApiException, IOException {
new GoogleDistance().go();
}
void go() throws InterruptedException, ApiException, IOException {
String API_KEY = "AIzy...";
GeoApiContext.Builder builder = new GeoApiContext.Builder();
builder.apiKey(API_KEY);
GeoApiContext geoApiContext = builder.build();
DistanceMatrix results1 = DistanceMatrixApi.getDistanceMatrix(geoApiContext,
new String[]{"los angeles"}, new String[]{"san francisco"}).units(Unit.METRIC).await();
DistanceMatrixRow[] rows = results1.rows;
for (DistanceMatrixRow row : rows) {
DistanceMatrixElement[] elements = row.elements;
for (DistanceMatrixElement element : elements) {
Distance distance = element.distance;
if(distance == null){
System.out.println("distance is null");
continue;
}
String dist = distance.humanReadable;
String dur = element.duration.humanReadable;
System.out.println(dist);
System.out.println(dur);
}
}
}
}
I believe you're getting null because google cant map between the locations you're providing.
Here is code of my getStream method:
public static Twitch_Stream getStream(String channelname) {
try {
String json = API.readJsonFromUrl("https://api.twitch.tv/kraken/streams?channel=" + channelname);
Twitch_Stream stream = new Twitch_Stream();
if (json.equalsIgnoreCase("[]")) {
stream.setOnline(false);
return stream;
}
JsonArray jb = gson.fromJson(json, JsonArray.class);
if (jb.size() != 0) {
JsonObject jo = (JsonObject) jb.get(0);
stream.setOnline(true);
stream.load(jo);
}
return stream;
} catch (Exception error) {
error.printStackTrace();
}
return null;
}
and here is code of Twitch_Stream class http://pastebin.com/3RX1L1cv
When I make something like this
Twitch_Stream streamer = Twitch_API.getStream("Jankos");
Bukkit.broadcastMessage("getName " + streamer.getName());
Bukkit.broadcastMessage(streamer.isOnline() + "");
streamer.getName() return null and streamer.isOnline() returns false, even when stream is on.
Where did I make a mistake?
I don't know what problem is in your code but simple workaround would be reading content from "https://api.twitch.tv/kraken/streams/" + channel which is JSON in format:
{
"_links" : {
//links to stream and channel
},
"stream" : {
//details about current stream
}
}
Now if value of stream key is null stream is off-line. If it is not null, it is on-line.
So your code can look like
public static void main(String[] argv) throws IOException {
System.out.println(checkIfOnline("Jankos"));
System.out.println(checkIfOnline("nightblue3"));
}
public static boolean checkIfOnline(String channel) throws IOException {
String channerUrl = "https://api.twitch.tv/kraken/streams/" + channel;
String jsonText = readFromUrl(channerUrl);// reads text from URL
JSONObject json = new JSONObject(jsonText);
return !json.isNull("stream");
}
private static String readFromUrl(String url) throws IOException {
URL page = new URL(url);
try (Stream<String> stream = new BufferedReader(new InputStreamReader(
page.openStream(), StandardCharsets.UTF_8)).lines()) {
return stream.collect(Collectors.joining(System.lineSeparator()));
}
}
I used JSONObject from org.json library. I am also using Java 8 and its streams.
If you want to use gson you can use instead something like
public static boolean checkIfOnline(String channel) throws IOException {
String channerUrl = "https://api.twitch.tv/kraken/streams/" + channel;
String jsonText = readFromUrl(channerUrl);// reads text from URL
JsonParser parser = new JsonParser();
JsonObject json = parser.parse(jsonText).getAsJsonObject();
return !json.get("stream").isJsonNull();
}
If you don't have Java 8 you can rewrite code reading text from URL to something like
private static String readFromUrl(String url) throws IOException {
URL page = new URL(url);
StringBuilder sb = new StringBuilder();
Scanner scanner = null;
try{
scanner = new Scanner(page.openStream(), StandardCharsets.UTF_8.name());
while (scanner.hasNextLine()){
sb.append(scanner.nextLine());
}
}finally{
if (scanner!=null)
scanner.close();
}
return sb.toString();
}
or from what I see you can use your API.readJsonFromUrl instead of readFromUrl.
Question : I want to change the hard coding json file path. The path will be from detailsListHM but I dont know how to do it.
Here is my main program
public class Program {
// hard coding json file path
private static final String filePath = "C:/appSession.json";
public static void main(String[] args)
{
taskManager();
}
public static void taskManager()
{
detailsHM = jsonParser(filePath);
}
public static HashMap<String, String> jsonParser(String jsonFilePath)
{
HashMap<String, String> detailsHM = new HashMap<String, String>();
String refGene = "";
try {
// read the json file
FileReader reader = new FileReader(filePath);
} catch (FileNotFoundException ex) {
ex.printStackTrace();
}
}
}
Here is another class called CustomConfiguration
public class CustomConfiguration {
private static HashMap<String, String> detailsListHM =new HashMap<String,String>();
public static void readConfig(String a) {
//read from config.properties file
try {
String result = "";
Properties properties = new Properties();
String propFileName = a;
InputStream inputStream = new FileInputStream(propFileName);
properties.load(inputStream);
// get the property value and print it out
String lofreqPath = properties.getProperty("lofreqPath");
String bamFilePath = properties.getProperty("bamFilePath");
String bamFilePath2 = properties.getProperty("bamFilePath2");
String resultPath = properties.getProperty("resultPath");
String refGenPath = properties.getProperty("refGenPath");
String filePath = properties.getProperty("filePath");
Set keySet = properties.keySet();
List keyList = new ArrayList(keySet);
Collections.sort(keyList);
Iterator itr = keyList.iterator();
while (itr.hasNext()) {
String key = (String) itr.next();
String value = properties.getProperty(key.toString());
detailsListHM.put(key, value);
}
} catch (IOException ex) {
System.err.println("CustomConfiguration - readConfig():" + ex.getMessage());
}
}
public static HashMap<String, String> getConfigHM() {
return detailsListHM;
}
Add a new property call "json-filepath" and read like
String filePath = properties.getProperty("json-filepath");
So the end user can change the json file path even during the runtime.
you can pass the filePath parameter by using the main parameters.
public static void main(String[] args) {
String filePath = null;
if(args.length > 0) {
filePath = args[0];
}
}
And invoke your main class like this:
java Program C:/appSession.json
I am writing a file that can parse rdf and owl files. I am using SAX and Java.
My problem is on the line activeObject.add(file);
I get the error "Syntax error on tokens, Misplaced construct(s)" - I don't know what this means. And it doesn't seem to make sense, any help would be much appreciated.
PS: I might be completely wrong about what is causing the error, it might have nothing to do with an inner class.
public static void main(String args[]) throws URISyntaxException, MalformedURLException, IOException {
// String file =
// "http://www.srdc.metu.edu.tr/ubl/contextOntology/cpc.owl";
// final String file = "http://onto.eva.mpg.de/obo/image.owl";
// final String file =
// "http://www.informatik.uni-ulm.de/ki/Liebig/owl/SUMO-LiteTB.rdf";
// final String file =
// "http://www.csd.abdn.ac.uk/~apreece/research/TowardsAnIntelligentWeb/PUB_findallbyKen_result.rdf";
// final String file =
// "http://www.srdc.metu.edu.tr/ubl/contextOntology/naics.owl";
final String file = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
URI uri = new URI(file);
InputStream is = uri.toURL().openStream();
try {
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser saxParser = factory.newSAXParser();
DefaultHandler handler = new DefaultHandler() {
ArrayList<String> activeProperty = new ArrayList<String>();
ArrayList<Triple> triplesList = new ArrayList<Triple>();
ArrayList<String> activeObject = new ArrayList<String>();
boolean name = false;
activeObject.add(file);
public void startElement(String uri, String localName,String qName, Attributes attributes) throws SAXException {
activeProperty.add(qName);
int attrLength = attributes.getLength();
for (int i = 0; i < attrLength; i++) {
String attrName = attributes.getQName(i).toLowerCase();
String attrValue = attributes.getValue(i).toLowerCase();
if (attrName.equals("rdf:about") || attrName.equals("rdf:resource") || attrName.equals("rdf:id")) {
activeObject.add(attrValue);
System.out.println(activeObject);
}
else{
String subject = activeObject.get(activeObject.size()-1);
String predicate = attrName;
String object = attrValue;
Triple newTriple = new Triple(subject, predicate, object);
}
}
}
public void characters(char[] ch, int start, int length) throws SAXException {
// tempVal = new String(ch, start, length);
}
public void endElement(String uri, String localName, String rawName) {
String subject = activeObject.get(activeObject.size()-2);
String predicate = activeProperty.get(activeProperty.size()-1);
String object = activeObject.get(activeObject.size()-1);
Triple newTriple = new Triple(subject,predicate, object);
if (rawName.equals(activeProperty.get(activeProperty.size() - 1))) {
activeProperty.remove(activeProperty.size() - 1);
}
else{
System.out.println("Something is seriosuly wrong ...sdf.sdf.we8ryw98fsydh");
}
// System.out.println(activeProperty);
}
// if (qName.equalsIgnoreCase("NAME")) {
// name = true;
// }
// public void characters(char ch[], int start, int length)
// throws SAXException {
// if (name) {
// System.out.println("Name: "
// + new String(ch, start, length));
// name = false;
// }
// }
};
saxParser.parse(is, handler);
} catch (Exception e) {
e.printStackTrace();
}
}
You're trying to write normal statements within an anonymous class, as if you'd tried this:
class Foo extends DefaultHandler {
ArrayList<String> activeProperty = new ArrayList<String>();
ArrayList<Triple> triplesList = new ArrayList<Triple>();
ArrayList<String> activeObject = new ArrayList<String>();
boolean name = false;
activeObject.add(file);
}
You can't do that. If you want this to be performed on construction, you can put it in an initializer block, like this:
ArrayList<String> activeProperty = new ArrayList<String>();
ArrayList<Triple> triplesList = new ArrayList<Triple>();
ArrayList<String> activeObject = new ArrayList<String>();
boolean name = false;
{
activeObject.add(file);
}
Or you could populate the list in some other way, perhaps - for instance with Guava you could write:
ArrayList<String> activeObject = Lists.newArrayList(file);
I'm trying to get the hits of a google search from a string of the query.
public class Utils {
public static int googleHits(String query) throws IOException {
String googleAjax = "http://ajax.googleapis.com/ajax/services/search/web?v=1.0&q=";
String json = stringOfUrl(googleAjax + query);
JsonObject hits = new Gson().fromJson(json, JsonObject.class);
return hits.get("estimatedResultCount").getAsInt();
}
public static String stringOfUrl(String addr) throws IOException {
ByteArrayOutputStream output = new ByteArrayOutputStream();
URL url = new URL(addr);
IOUtils.copy(url.openStream(), output);
return output.toString();
}
public static void main(String[] args) throws URISyntaxException, IOException {
System.out.println(googleHits("odp"));
}
}
The following exception is thrown:
Exception in thread "main" java.lang.NullPointerException
at odp.compling.Utils.googleHits(Utils.java:48)
at odp.compling.Utils.main(Utils.java:59)
What am I doing incorrectly? Should I be defining an entire object for the Json return? That seems excessive, given that all I want to do is get one value.
For reference: the returned JSON structure.
Looking the returned JSON, it seems that you're asking for the estimatedResultsCount member of the wrong object. You're asking for hits.estimatedResultsCount, but you need hits.responseData.cursor.estimatedResultsCount. I'm not super familiar with Gson, but I think you should do something like:
return hits.get("responseData").get("cursor").get("estimatedResultsCount");
I tried this and it worked, using JSON and not GSON.
public static int googleHits(String query) throws IOException,
JSONException {
String googleAjax = "http://ajax.googleapis.com/ajax/services/search/web?v=1.0&q=";
URL searchURL = new URL(googleAjax + query);
URLConnection yc = searchURL.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(
yc.getInputStream()));
String jin = in.readLine();
System.out.println(jin);
JSONObject jso = new JSONObject(jin);
JSONObject responseData = (JSONObject) jso.get("responseData");
JSONObject cursor = (JSONObject) responseData.get("cursor");
int count = cursor.getInt("estimatedResultCount");
return count;
}