how to fix java.io.IOException: Stream closed - java

I'm testing this class
/**
* Class to classify irises based on petal and sepal measurements.
*
* #author James Howard <jh#jameshoward.us>
*/
package us.jameshoward.iristypes;
import java.io.InputStream;
import java.util.Dictionary;
import java.util.Enumeration;
import weka.classifiers.Classifier;
import weka.core.Attribute;
import weka.core.FastVector;
import weka.core.Instance;
import weka.core.Instances;
import weka.core.SerializationHelper;
public class Iris {
private Classifier classModel;
private Instances dataModel;
private String classModelFile = "/Irises/etc/iris.model";
/**
* Class constructor.
*/
public Iris() throws Exception {
InputStream classModelStream;
// Create a stream object for the model file embedded
// within the JAR file.
classModelStream = getClass().getResourceAsStream(classModelFile);
classModel = (Classifier)SerializationHelper.read(classModelStream) ;
}
/**
* Close the instance by setting both the model file string and
* the model object itself to null. When the garbage collector
* runs, this should make clean up simpler. However, the garbage
* collector is not called synchronously since that should be
* managed by the larger execution environment.
*/
public void close() {
classModel = null;
classModelFile = null;
}
/**
* Evaluate the model on the data provided by #param measures.
* This returns a string with the species name.
*
* #param measures object with petal and sepal measurements
* #return string with the species name
* #throws Exception
*/
public String classifySpecies(Dictionary<String, String> measures) throws Exception {
#SuppressWarnings("rawtypes")
FastVector dataClasses = new FastVector();
FastVector dataAttribs = new FastVector();
Attribute species;
double values[] = new double[measures.size() + 1];
int i = 0, maxIndex = 0;
// Assemble the potential species options.
dataClasses.addElement("setosa");
dataClasses.addElement("versicolor");
dataClasses.addElement("virginica");
species = new Attribute("species", dataClasses);
// Create the object to classify on.
for (Enumeration<String> keys = measures.keys(); keys.hasMoreElements(); ) {
String key = keys.nextElement();
double val = Double.parseDouble(measures.get(key));
dataAttribs.addElement(new Attribute(key));
values[i++] = val;
}
dataAttribs.addElement(species);
dataModel = new Instances("classify", dataAttribs, 0);
dataModel.setClass(species);
dataModel.add(new Instance(1, values));
dataModel.instance(0).setClassMissing();
// Find the class with the highest estimated likelihood
double cl[] = classModel.distributionForInstance(dataModel.instance(0));
for(i = 0; i < cl.length; i++)
if(cl[i] > cl[maxIndex])
maxIndex = i;
return dataModel.classAttribute().value(maxIndex);
}
}
when start initialising its instance from another class with
Iris irisModel = new Iris();
i got following error
Exception in thread "main" java.io.IOException: Stream closed
at java.io.BufferedInputStream.getInIfOpen(BufferedInputStream.java:159)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:246)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:286)
at java.io.BufferedInputStream.read(BufferedInputStream.java:345)
at java.io.ObjectInputStream$PeekInputStream.read(ObjectInputStream.java:2320)
at java.io.ObjectInputStream$PeekInputStream.readFully(ObjectInputStream.java:2333)
at java.io.ObjectInputStream$BlockDataInputStream.readShort(ObjectInputStream.java:2804)
at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:802)
at java.io.ObjectInputStream.<init>(ObjectInputStream.java:299)
at weka.core.SerializationHelper.read(SerializationHelper.java:288)
at us.jameshoward.iristypes.Iris.<init>(Iris.java:33)
at us.jameshoward.iristypes.IrisDriver.main(IrisDriver.java:11)
I guess this error is case specific, by comparing with other posts, i still cant find out where it went wrong. in fact, this class was downloaded from IBMknowledge website, it supposes to be error-proof i guess.
anyone knows how to fix this?
thanks

Related

JPL Java Prolog Query fails

I have the following Prolog files:
(clauses.qa2.pl)
get(mary,milk,1).
go(john,bedroom,1).
go(sandra,kitchen,1).
go(mary,hallway,1).
get(john,football,1).
go(john,hallway,2).
drop(john,football,2).
go(mary,garden,2).
go(john,kitchen,3).
and (rules.pl)
/*This rule finds last location of a person */
isAt(X,Y) :- go(X, Y, T), \+ (go(X,_,T2), T2 > T).
/* This rule finds the last location of an object */
whereIs(Q,R) :- findall(R,(get(P,Q,I),go(P,R,_)),L), last(L,R),!.
along with the following java code:
import java.util.Hashtable;
import jpl.*;
import java.io.*;
import jpl.Query;
import java.util.Scanner;
public class PrologTest {
/**
* #param args the command line arguments
*/
public static void main(String[] args) throws IOException {
//include the prolog file with clauses to test
File clauseFile = new File ("C:\\Natural_Language_Final_Project\\PrologTest\\src\\clauses_qa2.pl");
File ruleFile = new File ("C:\\Natural_Language_Final_Project\\PrologTest\\src\\rules.pl");
String clausePath = clauseFile.getAbsolutePath();
String rulePath = ruleFile.getAbsolutePath();
System.out.println("Clause file path: " + clausePath);
System.out.println("Rule file path: " + rulePath);
Query q1 = new Query("consult",new Term[]{new Atom("C:\\Natural_Language_Final_Project\\PrologTest\\src\\clauses_qa2.pl")});
Query q2 = new Query("consult",new Term[]{new Atom("C:\\Natural_Language_Final_Project\\PrologTest\\src\\rules.pl")});
Scanner scan = new Scanner(ruleFile);
while (scan.hasNextLine()){
System.out.println(scan.nextLine());
}
jpl.JPL.init();
Variable X = new Variable("X");
Variable Y = new Variable ("Y");
Query q = new Query(new Compound("isAt",new Term[]{new Atom("john"),X}));
Hashtable solution = q.oneSolution();
System.out.println( "X = " + solution.get("X"));
}
The java code, given the Prolog should return X = kitchen. Instead, I get the following error:
Exception in thread "main" jpl.PrologException: PrologException:
error(existence_error(procedure, /(isAt, 3)), context(:(system, /('$c_call_prolog', 0)), _0))
at jpl.Query.get1(Query.java:336)
at jpl.Query.hasMoreSolutions(Query.java:258)
at jpl.Query.oneSolution(Query.java:688)
at PrologTest.main(PrologTest.java:43)
Any ideas on how to correct this?

A Strange Class Cast Exception in dumpToString

The following code generates the following odd exception:
package com.bmt.contain.spatial.test;
import org.neo4j.cypher.javacompat.ExecutionEngine;
import org.neo4j.cypher.javacompat.ExecutionResult;
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Relationship;
import org.neo4j.graphdb.ResourceIterator;
import org.neo4j.graphdb.Transaction;
import org.neo4j.graphdb.factory.GraphDatabaseFactory;
import org.neo4j.graphdb.factory.GraphDatabaseSettings;
import org.neo4j.graphdb.index.Index;
import org.neo4j.gis.spatial.indexprovider.SpatialIndexProvider;
import com.vividsolutions.jts.geom.Coordinate;
public class SpatialTest {
/**
* #param args
*/
public static void main(String[] args){
GraphDatabaseService graphDB = new GraphDatabaseFactory()
.newEmbeddedDatabaseBuilder("var/geo")
.setConfig(GraphDatabaseSettings.allow_store_upgrade, "true")
.newGraphDatabase();
Index<Node> index = null;
try (Transaction tx = graphDB.beginTx()){
index = createSpatialIndex(graphDB, "Coordinates");
tx.success();
}
Node ship = null;
try (Transaction tx = graphDB.beginTx();) {
ship = graphDB.createNode(MyLabels.Ship);
ship.setProperty("Name", new String("Phils Powerboat"));
tx.success();
}
routeGenerator(graphDB, ship, index);
try (Transaction tx = graphDB.beginTx()){
ExecutionEngine engine = new ExecutionEngine(graphDB);
ExecutionResult result = engine.execute("START n=node:Coordinates('withinDistance:[100, 9.3, 8.2]') RETURN n");
System.out.println(result.dumpToString());
}
try (Transaction tx = graphDB.beginTx();) {
ExecutionEngine engine = new ExecutionEngine(graphDB);
ExecutionResult result = engine.execute("MATCH (n) \n RETURN n");
System.out.println(result.dumpToString());
tx.success();
}
graphDB.shutdown();
}
/**
* This returns a new index unless an index with this name already exists, in which case it is returned.
* #param graphDb
* #param indexName
* #return
*/
private static Index<Node> createSpatialIndex(GraphDatabaseService graphDb, String indexName) {
return graphDb.index().forNodes(indexName, SpatialIndexProvider.SIMPLE_WKT_CONFIG);
}
private static void routeGenerator(GraphDatabaseService graphDb, Node startNode, Index<Node> index){
try (Transaction tx = graphDb.beginTx();) {
Coordinate start = new Coordinate(Math.random() * 10,
Math.random() * 10);
for (int i = 0; i < 20; i++) {
Node locationNode = graphDb.createNode(MyLabels.Location);
locationNode.setProperty("wkt", String.format("POINT(%s %s)", start.x, start.y));
Relationship rel = startNode.createRelationshipTo(locationNode, RelTypes.hasLocation);
start = new Coordinate((start.x + 0.1), start.x + Math.random()* 0.2);
}
tx.success();
}
}
}
This test is supposed to create a random route and return the nodes within a certain distance of the start point. However, the lines
ExecutionResult result = engine.execute("START n=node:Coordinates('withinDistance:[100, 9.3, 8.2]') RETURN n");
System.out.println(result.dumpToString());
Generate the error: "Exception in thread "main" java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.Double" - I have checked this by noting that commenting out the System.out line means that it runs just fine.
Note that i cleaned the directory before running this, and so there should be no other nodes in the directory. The full stack trace is below
Exception in thread "main" java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.Double
at org.neo4j.gis.spatial.indexprovider.LayerNodeIndex.query(LayerNodeIndex.java:228)
at org.neo4j.gis.spatial.indexprovider.LayerNodeIndex.query(LayerNodeIndex.java:290)
at org.neo4j.cypher.internal.spi.v2_0.TransactionBoundQueryContext$NodeOperations.indexQuery(TransactionBoundQueryContext.scala:169)
at org.neo4j.cypher.internal.compiler.v2_0.spi.DelegatingOperations.indexQuery(DelegatingQueryContext.scala:116)
at org.neo4j.cypher.internal.compiler.v2_0.spi.ExceptionTranslatingQueryContext$ExceptionTranslatingOperations.org$neo4j$cypher$internal$compiler$v2_0$spi$ExceptionTranslatingQueryContext$ExceptionTranslatingOperations$$super$indexQuery(ExceptionTranslatingQueryContext.scala:142)
at org.neo4j.cypher.internal.compiler.v2_0.spi.ExceptionTranslatingQueryContext$ExceptionTranslatingOperations$$anonfun$indexQuery$1.apply(ExceptionTranslatingQueryContext.scala:142)
at org.neo4j.cypher.internal.compiler.v2_0.spi.ExceptionTranslatingQueryContext$ExceptionTranslatingOperations$$anonfun$indexQuery$1.apply(ExceptionTranslatingQueryContext.scala:142)
at org.neo4j.cypher.internal.compiler.v2_0.spi.ExceptionTranslatingQueryContext.org$neo4j$cypher$internal$compiler$v2_0$spi$ExceptionTranslatingQueryContext$$translateException(ExceptionTranslatingQueryContext.scala:149)
at org.neo4j.cypher.internal.compiler.v2_0.spi.ExceptionTranslatingQueryContext$ExceptionTranslatingOperations.indexQuery(ExceptionTranslatingQueryContext.scala:142)
at org.neo4j.cypher.internal.compiler.v2_0.spi.DelegatingOperations.indexQuery(DelegatingQueryContext.scala:116)
at org.neo4j.cypher.internal.compiler.v2_0.executionplan.builders.EntityProducerFactory$$anonfun$2$$anonfun$applyOrElse$2.apply(EntityProducerFactory.scala:66)
at org.neo4j.cypher.internal.compiler.v2_0.executionplan.builders.EntityProducerFactory$$anonfun$2$$anonfun$applyOrElse$2.apply(EntityProducerFactory.scala:64)
at org.neo4j.cypher.internal.compiler.v2_0.executionplan.builders.EntityProducerFactory$$anon$1.apply(EntityProducerFactory.scala:35)
at org.neo4j.cypher.internal.compiler.v2_0.executionplan.builders.EntityProducerFactory$$anon$1.apply(EntityProducerFactory.scala:34)
at org.neo4j.cypher.internal.compiler.v2_0.pipes.StartPipe$$anonfun$internalCreateResults$1.apply(StartPipe.scala:34)
at org.neo4j.cypher.internal.compiler.v2_0.pipes.StartPipe$$anonfun$internalCreateResults$1.apply(StartPipe.scala:33)
at scala.collection.Iterator$$anon$13.hasNext(Iterator.scala:371)
at org.neo4j.cypher.internal.compiler.v2_0.ClosingIterator$$anonfun$hasNext$1.apply$mcZ$sp(ClosingIterator.scala:35)
at org.neo4j.cypher.internal.compiler.v2_0.ClosingIterator$$anonfun$hasNext$1.apply(ClosingIterator.scala:34)
at org.neo4j.cypher.internal.compiler.v2_0.ClosingIterator$$anonfun$hasNext$1.apply(ClosingIterator.scala:34)
at org.neo4j.cypher.internal.compiler.v2_0.ClosingIterator.failIfThrows(ClosingIterator.scala:89)
at org.neo4j.cypher.internal.compiler.v2_0.ClosingIterator.hasNext(ClosingIterator.scala:34)
at scala.collection.Iterator$class.foreach(Iterator.scala:727)
at org.neo4j.cypher.internal.compiler.v2_0.ClosingIterator.foreach(ClosingIterator.scala:30)
at scala.collection.generic.Growable$class.$plus$plus$eq(Growable.scala:48)
at scala.collection.mutable.ListBuffer.$plus$plus$eq(ListBuffer.scala:176)
at scala.collection.mutable.ListBuffer.$plus$plus$eq(ListBuffer.scala:45)
at scala.collection.TraversableOnce$class.to(TraversableOnce.scala:273)
at org.neo4j.cypher.internal.compiler.v2_0.ClosingIterator.to(ClosingIterator.scala:30)
at scala.collection.TraversableOnce$class.toList(TraversableOnce.scala:257)
at org.neo4j.cypher.internal.compiler.v2_0.ClosingIterator.toList(ClosingIterator.scala:30)
at org.neo4j.cypher.internal.compiler.v2_0.PipeExecutionResult.eagerResult(PipeExecutionResult.scala:101)
at org.neo4j.cypher.internal.compiler.v2_0.PipeExecutionResult.dumpToString(PipeExecutionResult.scala:107)
at org.neo4j.cypher.internal.compiler.v2_0.PipeExecutionResult.dumpToString$lzycompute(PipeExecutionResult.scala:152)
at org.neo4j.cypher.internal.compiler.v2_0.PipeExecutionResult.dumpToString(PipeExecutionResult.scala:149)
at org.neo4j.cypher.javacompat.ExecutionResult.dumpToString(ExecutionResult.java:102)
at com.bmt.contain.spatial.test.Initialise.main(Initialise.java:46)
Solution 1 {If you only want string representation of the node}
ExecutionResult result = engine.execute("START n=node:Coordinates('withinDistance:[100, 9.3, 8.2]') RETURN str(n)");
System.out.println(result.dumpToString());
Solution 2 {if you wish to iterate over node and its properties}
ResourceIterator<Node> resultIterator;
ExecutionResult result = engine.execute("START n=node:Coordinates('withinDistance:[100, 9.3, 8.2]') RETURN n");
resultIterator = result.columnAs("n");
while(resultIterator.hasNext()){
System.out.println(resultIterator.next());
}
resultIterator.close();
If the above two queries fail then you might want to try what is suggested in the comments

How to read a java.util.InputMismatchException stack trace

I am struggling to read this stack trace exception below. I wonder If you could help me?
I don't understand any of the numbers in the code (like the number 74, 2119 and 2160, what do they represent in this exception? Quite literally, I need to know which line of my code is causing problems so that I can resolve it. Please help.
Here below is my stack trace, and beneath it is the java code I am trying to resolve alongside a sample input file which came with the task.
java.util.InputMismatchException
in java.util.Scanner.throwFor(Scanner.java:909)
in java.util.Scanner.next(Scanner.java:1530)
in java.util.Scanner.nextInt(Scanner.java:2160)
in java.util.Scanner.nextInt(Scanner.java:2119)
in League.loadLeague(League.java:74)
in (Workspace:1)
And here, below is my Java code with the method loadLeague which is causing me a lot of headache!
import java.io.*;
import java.util.*;
/**
* Class League - An instance of this class represents the teams in a
* football (or similar) league. It provides a class method for creating
* a new instance of League by reading the data for the teams from a CSV
* file.
*
* #author Lewis Jones
* #version 1.0
*/
public class League
{
/* instance variables */
private String name; // The name of the league
private Team[] teams; // An array to hold the teams in the league
/**
* Constructor for objects of class League. It sets the name of the league
* to the String object provided as the first argument and initialises teams
* to an array of the size provided as the second argument. This constructor
* is private as it is intended for use only by the class method loadLeague().
*/
private League(String aName, int size)
{
super();
this.name = aName;
this.teams = new Team[size];
}
/* class method */
/**
* This method creates a new League object by reading the required details from
* a CSV file. The file must be organised as follows:
* name(String), number of teams (int)
* team name(String), won(int), drawn(int), lost(int), for(int), against (int)
* and so on for each team
* Having created the new League object the method should create all the Team
* objects (using the data in the file to set their attributes) and add them
* to the teams array.
*/
public static League loadLeague()
{
League theLeague = null;
String pathname = OUFileChooser.getFilename();
File aFile = new File(pathname);
Scanner bufferedScanner = null;
try
{
String leagueName;
int numberOfTeams;
String teamName;
int won;
int drawn;
int lost;
int goalsFor;
int goalsAgainst;
Scanner lineScanner;
String currentLine;
bufferedScanner = new Scanner(new BufferedReader(new FileReader (aFile)));
while (bufferedScanner.hasNextLine())
{
currentLine = bufferedScanner.nextLine();
lineScanner = new Scanner(currentLine);
lineScanner.useDelimiter(",");
leagueName = bufferedScanner.next();
numberOfTeams = bufferedScanner.nextInt();
teamName = bufferedScanner.next();
won = lineScanner.nextInt();
drawn = lineScanner.nextInt();
lost = lineScanner.nextInt();
goalsFor = lineScanner.nextInt();
goalsAgainst = lineScanner.nextInt();
Team aTeam = new Team(lineScanner.next());
aTeam.setWon(lineScanner.nextInt());
aTeam.setDrawn(lineScanner.nextInt());
aTeam.setLost(lineScanner.nextInt());
aTeam.setGoalsFor(lineScanner.nextInt());
aTeam.setGoalsAgainst(lineScanner.nextInt());
Team[] teams = new Team[numberOfTeams];
teams[numberOfTeams] = aTeam;
numberOfTeams++;
theLeague = new League(leagueName, numberOfTeams);
}
}
catch (Exception anException)
{
System.out.println("Error: " + anException);
}
finally
{
try
{
bufferedScanner.close();
}
catch (Exception anException)
{
System.out.println("Error: " + anException);
}
}
return theLeague;
}
/* instance methods */
/**
* Displays the league table in tabular format to the standard output
*/
public void display()
{
System.out.println(this.name);
System.out.format("%20s %2s %2s %2s %2s %2s %2s % 2s\n","","P","W","L","D","F","A","Pt");
for (Team eachTeam : this.teams)
{
System.out.format("%20s %2d %2d %2d %2d %2d %2d %2d\n",
eachTeam.getName(), eachTeam.getPlayed(),
eachTeam.getWon(), eachTeam.getDrawn(),
eachTeam.getLost(),eachTeam.getGoalsFor(),
eachTeam.getGoalsAgainst(), eachTeam.getPoints());
}
}
/**
* Arrange the elements of teams in their natural order. This will only
* work if a natural order has been defined for the class Team.
*/
public void sort()
{
// to be written later...
}
}
And below is the sample (file) input which the program is supposed to read into:
Scottish League Division 1,10
Airdrie United ,3,2,11,14,25
Clyde ,5,7,4,21,17
Dundee ,7,2,7,21,18
Gretna ,10,3,3,43,20
Hamilton Acas ,7,5,4,19,20
Livingstone ,6,6,4,21,15
Partick Thistle,8,4,4,25,29
Queen of South ,3,3,10,11,31
Ross County ,4,4,8,14,24
St Johnstone ,6,6,4,26,16
I have really struggled with this task for nearly a week now! I hope someone out there comes to my rescue as it's really getting on my skin now. Please help. Any tips to pinpoint which code I'm writing wrongly would be so much appreciated.
Thank you guys,
Lew.
Those numbers (74, 2119 and 2160) are the code lines. The top most line of the stack trace is where the actual error occurred, and the rest are the call locations in the stack trace.
So in this event, Scanner.java:909 means that the error occurred at line 909 of the Scanner class, which was in a function called at line 1530 in Scanner, and so on and so forth.

Why is there a Null Pointer Exception in this Java Code?

This code takes in users and movies from two separate files and computes a user score for a movie. When I run the code I get the following error:
Exception in thread "main" java.lang.NullPointerException
at RecommenderSystem.makeRecommendation(RecommenderSystem.java:75)
at RecommenderSystem.main(RecommenderSystem.java:24)
I believe the NullPointerException is due to an error in this particular class but I can't spot it. Any thoughts?
import java.io.*;
import java.lang.Math;
public class RecommenderSystem
{
private Movie[] m_movies;
private User[] m_users;
/** Parse the movies and users files, and then run queries against them.
*/
public static void main(String[] argv)
throws FileNotFoundException, ParseError, RecommendationError
{
FileReader movies_fr = new FileReader("C:\\workspace\\Recommender\\src\\IMDBTop10.txt");
FileReader users_fr = new FileReader("C:\\workspace\\Recommender\\src\\IMDBTop10-users.txt");
MovieParser mp = new MovieParser(movies_fr);
UserParser up = new UserParser(users_fr);
Movie[] movies = mp.getMovies();
User[] users = up.getUsers();
RecommenderSystem rs = new RecommenderSystem(movies, users);
System.out.println("Alice would rate \"The Shawshank Redemption\" with at least a "
+ rs.makeRecommendation("The Shawshank Redemption", "asmith"));
System.out.println("Carol would rate \"The Dark Knight\" with at least a "
+ rs.makeRecommendation("The Dark Knight", "cd0"));
}
/** Instantiate a recommender system.
*
* #param movies An array of Movie that will be copied into m_movies.
* #param users An array of User that will be copied into m_users.
*/
public RecommenderSystem(Movie[] movies, User[] users)
throws RecommendationError
{
m_movies = movies;
m_users = users;
}
/** Suggest what the user with "username" would rate "movieTitle".
*
* #param movieTitle The movie for which a recommendation is made.
* #param username The user for whom the recommendation is made.
*/
public double makeRecommendation(String movieTitle, String username)
throws RecommendationError
{
int userNumber;
int movieNumber;
int j=0;
double weightAvNum =0;
double weightAvDen=0;
for (userNumber = 0; userNumber < m_users.length; ++userNumber)
{
if (m_users[userNumber].getUsername().equals(username))
{
break;
}
}
for (movieNumber = 0; movieNumber < m_movies.length; ++movieNumber)
{
if (m_movies[movieNumber].getTitle().equals(movieTitle))
{
break;
}
}
// Use the weighted average algorithm here (don't forget to check for
// errors).
while(j<m_users.length){
if(j!=userNumber){
weightAvNum = weightAvNum + (m_users[j].getRating(movieNumber)- m_users[j].getAverageRating())*(m_users[userNumber].similarityTo(m_users[j]));
weightAvDen = weightAvDen + (m_users[userNumber].similarityTo(m_users[j]));
}
j++;
}
return (m_users[userNumber].getAverageRating()+ (weightAvNum/weightAvDen));
}
}
class RecommendationError extends Exception
{
/** An error for when something goes wrong in the recommendation process.
*
* #param s A string describing the error.
*/
public RecommendationError(String s)
{
super(s);
}
}
If the file you posted is unaltered from the file that generated the stack trace you posted, then the nullpointer exception on line 75 is somewhere in this code:
weightAvNum = weightAvNum + (m_users[j].getRating(movieNumber)- m_users[j].getAverageRating())*(m_users[userNumber].similarityTo(m_users[j]));
So since m_users is not null (otherwise it would have crashed earlier) either m_users[j] or m_users[userNumber] is null, i.e., there is some null element in the m_users array.

Apple pList form of XML can I parse it through Android Java? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 7 years ago.
Improve this question
Can we parse the iPhone/iPad based pList XML from Java on Android?
Please tell me if any such library you have used or know about?
Here is a class I wrote to parse an xml plist file. It uses the XmlPullParser to do the parsing. I have only implemented what I needed for my project. But this should get you started for extending the class if you need more than what this class provides.
File : XMLPropertyListConfiguration.java
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.example.plist;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Stack;
import org.xmlpull.v1.XmlPullParser;
import android.annotation.SuppressLint;
import android.util.Xml;
//import android.util.Log;
/**
* This class will parse a plist xml file and store the contents in a
* hierarchical HashMap of <String, Object> tuples, where the Object value could
* be another HashMap, an ArrayList, Boolean, Date, String or Integer value.
*
* Use the getConfiguration methods to retrieve the values from the parsed plist
* file.
*
* The key names for nested dictionary references must be of the form :
* Dict1KeyName.Dict2KeyName.ElementKeyName
*
* #author akoscz
*
*/
public class XMLPropertyListConfiguration {
// private static final String TAG = "plist";
/**
* The nested (hierarchical) HashMap which holds our key-value pairs of our
* plist file.
*/
protected HashMap<String, Object> mPlistHashMap;
/**
* Constructor. Parse a plist file from the given InputStream.
*
* #param inputStream
* The InputStream which has the bytes of the plist file we need
* to parse.
*/
public XMLPropertyListConfiguration(InputStream inputStream) {
mPlistHashMap = new HashMap<String, Object>();
if (inputStream != null) {
parse(inputStream);
}
}
/**
* Get an String configuration value for the given key.
*
* #param keyName
* The name of the key to look up in the configuration
* dictionary.
* #return The String value of the specified key.
*/
public String getConfiguration(String keyName) {
return (String) getConfigurationObject(keyName);
}
/**
* Get a String configuration value for the given key. If there is no value
* for the given key, then return the default value.
*
* #param keyName
* The name of the key to look up in the configuration
* dictionary.
* #param defaultValue
* The default value to return if they key has no associated
* value.
* #return The String value of the specified key, or defaultValue if the
* value for keyName is null.
*/
public String getConfigurationWithDefault(String keyName, String defaultValue) {
String value = getConfiguration(keyName);
if (value == null) {
return defaultValue;
}
return value;
}
/**
* Get an Integer configuration value for the given key.
*
* #param keyName
* The name of the key to look up in the configuration
* dictionary.
* #return The Integer value of the specified key.
*/
public Integer getConfigurationInteger(String keyName) {
return (Integer) getConfigurationObject(keyName);
}
/**
* Get an Integer configuration value for the given key. If there is no
* value for the given key, then return the default value.
*
* #param keyName
* The name of the key to look up in the configuration
* dictionary.
* #param defaultValue
* The default value to return if they key has no associated
* value.
* #return The Integer value of the specified key, or defaultValue if the
* value for keyName is null.
*/
public Integer getConfigurationIntegerWithDefault(String keyName, Integer defaultValue) {
Integer value = getConfigurationInteger(keyName);
if (value == null) {
return defaultValue;
}
return value;
}
/**
* Get a Date configuration value for the given key.
*
* #param keyName
* The name of the key to look up in the configuration
* dictionary.
* #return The Date value of the specified key.
*/
public Date getConfigurationDate(String keyName) {
return (Date) getConfigurationObject(keyName);
}
/**
* Get a Date configuration value for the given key. If there is no value
* for the given key, then return the default value.
*
* #param keyName
* The name of the key to look up in the configuration
* dictionary.
* #param defaultValue
* The default value to return if they key has no associated
* value.
* #return The Date value of the specified key, or defaultValue if the value
* for keyName is null.
*/
public Date getConfigurationDateWithDefault(String keyName, Date defaultValue) {
Date value = getConfigurationDate(keyName);
if (value == null) {
return defaultValue;
}
return value;
}
/**
* Get a Boolean configuration value for the given key.
*
* #param keyName
* The name of the key to look up in the configuration
* dictionary.
* #return The Boolean value of the specified key.
*/
public Boolean getConfigurationBoolean(String keyName) {
return (Boolean) getConfigurationObject(keyName);
}
/**
* Get a Boolean configuration value for the given key. If there is no
* value for the given key, then return the default value.
*
* #param keyName
* The name of the key to look up in the configuration
* dictionary.
* #param defaultValue
* The default value to return if they key has no associated
* value.
* #return The Boolean value of the specified key, or defaultValue if the
* value for keyName is null.
*/
public Boolean getConfigurationBooleanWithDefault(String keyName,
Boolean defaultValue) {
Boolean value = getConfigurationBoolean(keyName);
if (value == null) {
return defaultValue;
}
return value;
}
/**
* Utility method which uses a XmlPullParser to iterate through the XML
* elements and build up a hierarchical HashMap representing the key-value
* pairs of the plist configuration file.
*
* #param inputStream
* The InputStream which contains the plist XML file.
*/
public void parse(InputStream inputStream) {
mPlistHashMap.clear();
XmlPullParser parser = Xml.newPullParser();
try {
parser.setInput(inputStream, null);
int eventType = parser.getEventType();
int arrayDepth = 0;
boolean done = false;
boolean parsingArray = false;
String name = null;
String key = null;
Stack<HashMap<String, Object>> stack = new Stack<HashMap<String, Object>>();
HashMap<String, Object> dict = null;
ArrayList<Object> array = null;
while (eventType != XmlPullParser.END_DOCUMENT && !done) {
switch (eventType) {
case XmlPullParser.START_DOCUMENT:
// Log.d(TAG, "START_DOCUMENT");
break;
case XmlPullParser.START_TAG:
name = parser.getName();
if (name.equalsIgnoreCase("dict")) {
// root dict element
if (key == null) {
mPlistHashMap.clear();
dict = mPlistHashMap;
} else if (parsingArray) {
// Log.d(TAG, "START_TAG dict : inside array");
HashMap<String, Object> childDict = new HashMap<String, Object>();
array.add(childDict);
stack.push(dict);
dict = childDict;
} else {
// Log.d(TAG, "START_TAG dict : " + key);
HashMap<String, Object> childDict = new HashMap<String, Object>();
dict.put(key, childDict);
stack.push(dict);
dict = childDict;
}
} else if (name.equalsIgnoreCase("key")) {
key = parser.nextText();
} else if (name.equalsIgnoreCase("integer")) {
dict.put(key, Integer.valueOf(parser.nextText()));
} else if (name.equalsIgnoreCase("string")) {
if (parsingArray && (parser.getDepth() == (arrayDepth + 1))) {
array.add(parser.nextText());
} else {
dict.put(key, parser.nextText());
}
} else if (name.equalsIgnoreCase("array")) {
parsingArray = true;
array = new ArrayList<Object>();
dict.put(key, array);
arrayDepth = parser.getDepth();
} else if (name.equalsIgnoreCase("date")) {
dict.put(key, parseDate(parser.nextText()));
} else if (name.equalsIgnoreCase("true")) {
dict.put(key, Boolean.TRUE);
} else if (name.equalsIgnoreCase("false")) {
dict.put(key, Boolean.FALSE);
}
break;
case XmlPullParser.END_TAG:
name = parser.getName();
if (name.equalsIgnoreCase("dict")) {
// Log.d(TAG, "END_TAG dict");
if (!stack.empty()) {
dict = stack.pop();
}
} else if (name.equalsIgnoreCase("array")) {
parsingArray = false;
array = null;
} else if (name.equalsIgnoreCase("plist")) {
done = true;
}
break;
case XmlPullParser.END_DOCUMENT:
// Log.d(TAG, "END_DOCUMENT");
break;
}
eventType = parser.next();
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
/**
* Method to parse an ISO8601 string to a Date object.
* http://www.java2s.com/Code/Java/Data-Type/ISO8601dateparsingutility.htm
*
* #param input
* The ISO8601 date string
* #return The Date object representing the ISO8601 date string.
* #throws java.text.ParseException
*/
#SuppressLint("SimpleDateFormat")
public static Date parseDate(String input) throws java.text.ParseException {
// NOTE: SimpleDateFormat uses GMT[-+]hh:mm for the TZ which breaks
// things a bit. Before we go on we have to repair this.
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssz");
// this is zero time so we need to add that TZ indicator for
if (input.endsWith("Z")) {
input = input.substring(0, input.length() - 1) + "GMT-00:00";
} else {
int inset = 6;
String s0 = input.substring(0, input.length() - inset);
String s1 = input.substring(input.length() - inset, input.length());
input = s0 + "GMT" + s1;
}
return df.parse(input);
}
/**
* Utility method which tokenizes the given keyName using the "." delimiter
* and then looks up each token in the configuration dictionary. If the
* token key points to a dictionary then it proceeds to the next token key
* and looks up value of the token key in the dictionary it found from the
* previous token key.
*
* #param keyName
* The fully qualified key name.
* #return The Object value associated with the given key, or null if the
* key does not exist.
*/
#SuppressWarnings("unchecked")
protected Object getConfigurationObject(String keyName) {
String[] tokens = keyName.split("\\.");
if (tokens.length > 1) {
HashMap<String, Object> dict = mPlistHashMap;
Object obj;
for (int i = 0; i < tokens.length; i++) {
obj = dict.get(tokens[i]);
if (obj instanceof HashMap<?, ?>) {
dict = (HashMap<String, Object>) obj;
continue;
}
return obj;
}
}
return mPlistHashMap.get(keyName);
}
}
Following is a convenience class which extends XMLPropertyListConfiguration to encapsulate the logic of parsing your domain specific plist file. The getter methods are simple delegates to the parent class getConfiguration() methods. Note that you can specify default values to be returned if the key is not present in the plist file.
I have also added some debug methods to print out the keys and values to the debug log.
File : ExamplePListParser.java
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.example.plist;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;
import android.util.Log;
public class ExamplePListParser extends XMLPropertyListConfiguration {
private static final String TAG = "ExamplePListParser";
public ExamplePListParser(InputStream inputStream) {
super(inputStream);
}
public Integer getVersion() {
return getConfigurationIntegerWithDefault("Version", 1);
}
public String getUrl() {
return getConfigurationWithDefault("Url", "http://");
}
public Integer getBrowserVideoWidth(){
return getConfigurationIntegerWithDefault("Browser.VideoWidth", 1280);
}
public Integer getBrowserVideoHeight(){
return getConfigurationIntegerWithDefault("Browser.VideoHeight", 800);
}
public String getRating() {
return getConfigurationWithDefault("Rating", "G");
}
public Date getExpireDate() {
return getConfigurationDateWithDefault("ExpireDate", new Date());
}
public Boolean getHighRes() {
return getConfigurationBooleanWithDefault("HighRes", Boolean.TRUE);
}
/**
* Debug method. Print all the "dict" key names from our plist configuration
* file
*/
public void dumpKeys() {
printHashKeys("root", mPlistHashMap);
}
/**
* Debug method. Iterate through all the methods of this class and print our
* the resulting values.
*/
public void dumpValues() {
try {
Class<? extends XMLPropertyListConfiguration> c = this.getClass();
Method m[] = c.getDeclaredMethods();
for (int i = 0; i < m.length; i++) {
// only invoke getter methods
if (m[i].getName().startsWith("get")) {
// Log.d(TAG, m[i].getName());
if (m[i].getReturnType() == Integer.class) {
Log.d(TAG, m[i].getName() + " --> " + (Integer) m[i].invoke(this, (Object[]) null));
} else if (m[i].getReturnType() == ArrayList.class) {
Log.d(TAG, m[i].getName() + " --> Array");
dumpArrayList((ArrayList<?>) m[i].invoke(this, (Object[]) null));
} else if (m[i].getReturnType() == Date.class) {
Log.d(TAG, m[i].getName() + " --> " + (Date) m[i].invoke(this, (Object[]) null));
} else if (m[i].getReturnType() == Boolean.class) {
Log.d(TAG, m[i].getName() + " --> " + (Boolean) m[i].invoke(this, (Object[]) null));
} else if (m[i].getReturnType() == String.class) {
Log.d(TAG, m[i].getName() + " --> " + (String) m[i].invoke(this, (Object[]) null));
} else {
Log.d(TAG, m[i].getName() + " --> UNSUPPORTED TYPE");
}
}
}
} catch (Throwable e) {
e.printStackTrace();
}
}
private void dumpArrayList(ArrayList<?> list) {
for (Iterator<?> iter = list.iterator(); iter.hasNext();) {
Object o = iter.next();
if (o instanceof String) {
Log.d(TAG, "\t" + (String) o);
} else if (o instanceof Integer) {
Log.d(TAG, "\t" + (Integer) o);
} else if (o instanceof HashMap) {
Log.d(TAG, "\tHashMap");
#SuppressWarnings("unchecked")
HashMap<String, Object> hash = (HashMap<String, Object>) o;
for (Iterator<String> hashIter = hash.keySet().iterator(); hashIter.hasNext();) {
String key = hashIter.next();
Object value = hash.get(key);
if (value instanceof Integer) {
Log.d(TAG, "\t\t " + key + " = " + (Integer) value);
} else if (value instanceof String) {
Log.d(TAG, "\t\t " + key + " = " + (String) value);
}
}
}
}
}
/**
* Debug method. Iterate through all the keys in the HashMap (dict) and
* print the key names for each child HashMap (dict).
*/
#SuppressWarnings("unchecked")
private void printHashKeys(String key, HashMap<String, Object> map) {
Set<String> keys = map.keySet();
Log.d(TAG, key + " --> " + keys.toString());
for (Iterator<String> iter = keys.iterator(); iter.hasNext();) {
key = iter.next();
Object o = map.get(key);
if (o instanceof HashMap) {
printHashKeys(key, (HashMap<String, Object>) o);
}
}
}
}
Here is a sample plist file.
File : sample.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Version</key>
<integer>3</integer>
<key>Url</key>
<string>http://example.com/video.mp4</string>
<key>ExpireDate</key>
<date>2013-4-20T11:20:00Z</date>
<key>HighRes</key>
<false/>
<key>Browser</key>
<dict>
<key>VideoWidth</key>
<integer>640</integer>
<key>VideoHeight</key>
<integer>480</integer>
</dict>
</dict>
</plist>
Sample Usage :
ExamplePListParser mPListParser;
InputStream inputStream = new FileInputStream("/sdcard/sample.xml");
if(mPListParser == null) {
mPListParser = new ExamplePListParser(inputStream);
} else {
mPListParser.parse(inputStream);
}
int version = mPListParser.getVersion();
int height = mPListParser.getBrowserVideoHeight();
int width = mPListParser.getBrowserVideoWidth();
String url = mPListParser.getUrl();
String rating = mPListParser.getRating();
Date expireDate = mPListParser.getExpireDate();
boolean highRes = mPListParser.getHighRes();
// debug: print out keys and values
mPListParser.dumpKeys();
mPListParser.dumpValues();
Try it
http://code.google.com/p/xmlwise/
I'm testing it right now.
Since a plist is just an XML file, you can use any of the available XML parsers. Personally, I use XmlPullParser for small files.
Akos' code is imo the best response to this question so far. However, his algorithm does not work for nested arrays, and it doesn't support all PList tags. I'm working on a more generalized SAX-based implementation for PList parsing in Android. I'll post the code on my blog upon request.
The PList parser I promised can be found at: https://github.com/tenaciousRas/android-plist-parser
Have fun!
This isn't exactly what you asked but it is what I did rather than add a code dependency to my project.
You can convert the PList file to a JSON file and use the built in JSON parser. There is a tool to do this on OSX which comes with the developer tools (I think, that or it is just installed by default).
plutil -convert json Days.plist

Categories

Resources