In the following Java program (only showing a part of the whole program)
I have the follwing code:
private final File test_data_file;
private final int algorithm_selection;
private double average_pos_err, average_exe_time;
// The scan list to use for offline
private ArrayList<LogRecord> OfflineScanList;
public OfflineMode(RadioMap RM, File test_data_file, int algorithm_selection, Handler handler) {
this.RM = RM;
this.test_data_file = test_data_file;
this.handler = handler;
this.algorithm_selection = algorithm_selection;
this.OfflineScanList = new ArrayList<LogRecord>();
}
public void run() {
if (!test_data_file.isFile() || !test_data_file.exists() || !test_data_file.canRead()) {
errMsg = test_data_file + " does not exist or is not readable";
handler.sendEmptyMessage(-1);
return;
}
I want to track down, the path of the variable "test_data_file" of type File, but the code does not seems to show me any directions.
do you know where I can find it?
Thank you.
You can use File#getAbsolutePath or File#getCanonicalPath which will resolve the path fully (removing relative components)
using by java 7 you can get file type
String fileType = Files.probeContentType(test_data_file.getPath());
for more detail you can refers
http://docs.oracle.com/javase/7/docs/api/java/nio/file/Files.html#probeContentType%28java.nio.file.Path%29
Related
I am trying to convert string-array from strings.xml to array in Java class
(the model part of MVC), there-for I cannot use getResources().getStringArray(R.array.array_name);
(it works only in Android components such as activity, fragment and so on).
So I can use only Resources.getSystem().getStringArray(R.array.array_name);
but When I try to run it in the emulator, I get an exception.
I found similar questions that referred that problem here. but I didn't understand the solution.
Here my exception:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.danirg10000gmail.therpiststep1/com.danirg10000gmail.therpiststep1.MainActivity}: android.content.res.Resources$NotFoundException: String array resource ID #0x7f0b0000
(My exception is same as in the link above.)
In my code I have two classes one class represents questions, another class have a list of questions objects.
Here is my code:
public class QuestionM {
private String mQuestion;
private String mAnswer;
private String mExplanation;
//constructor
public QuestionM(String question,String explanation) {
mQuestion = question;
mExplanation = explanation;
}
public class QuestionnaireM {
private List<QuestionM> mQuestionsList;
//constructor
public QuestionnaireM(){
mQuestionsList = new ArrayList<>();
Resources resources = Resources.getSystem();
//when i creating object of that class android points the crush here
String [] questions = resources.getStringArray(R.array.test);
String [] questionExplanations = resources.getStringArray(R.array.test_a);
for (int i=0; i<questions.length; i++){
QuestionM question = new QuestionM(questions[i],questionExplanations[i]);
mQuestionsList.add(question);
}
}
also I didn't quite understand the difference between system-level resources, and application-level resources, I search it in androidDevelopers and in Google but not found any good explanation. can somebody please explain that?
One suggestion, not sure if it will work. But you can try and let me know. Why not get the context in QuestionM constructor and initialize your class level context variable with the received context. Now use this context to
mContext.getResources().getStringArray(R.array.array_name);
public class QuestionM {
private String mQuestion;
private String mAnswer;
private String mExplanation;
private Context mContext;
//constructor
public QuestionM(String question,String explanation, Context context) {
mQuestion = question;
mExplanation = explanation;
mContext = context;
}
public class QuestionnaireM {
private List<QuestionM> mQuestionsList;
//constructor
public QuestionnaireM(){
mQuestionsList = new ArrayList<>();
//when i creating object of that class android points the crush here
String [] questions = mContext.getResources().getStringArray(R.array.test);
String [] questionExplanations = mContext.getResources().getStringArray(R.array.test_a);
for (int i=0; i<questions.length; i++){
QuestionM question = new QuestionM(questions[i],questionExplanations[i]);
mQuestionsList.add(question);
}
}
According to the docs getSystem() does this:
Return a global shared Resources object that provides access to only
system resources (no application resources), and is not configured for
the current screen (can not use dimension units, does not change based
on orientation, etc).
Therefore calling getStringArray() with the resource Id R.array.test is totally useless since the id referenced is that of an Application resource.
If you want to load the contents of R.array.test, use getStringArray() from getResources().
You can pass a parameter of type Resources to the constructor or String[]. i.e. :
public QuestionnaireM(Resources resource) {
// stuffs
}
I'm trying use Preferences API to save a path to file in regedit. It is works but the value of path is not saved correctly.
I'm trying this.
public class ImageLogoPreference {
private final String path = "configs";
private Preferences node;
public ImageLogoPreference(){
node = Preferences.userRoot().node(path);
}
public void setImageLogo(){
node.put("logo", "\\IguanaSistemas\\IguanaFight\\imagens\\logo.png");
}
public String getImageLogo(){
String logo = node.get("logo", "image");
return logo;
}
}
At register save this: ///Iguana/Sistemas///Iguana/Fight//imagens//logo.png
Any idea ?
Doesn't matter.
Just get it in your Java program. You don't have a problem.
Preferences node = Preferences.userRoot().node("config");
//node.put("logo", "\\IguanaSistemas\\IguanaFight\\imagens\\logo.png");
String s = node.get("logo", "blah");
System.out.println(s);
Prints the correct string.
I am trying to save a GraphStream/NetStream from NetLogo do *.gexf file. Graph has constant number of edges and vertices. Thing that is changing is parameters of nodes/'turtles'. Currently, after each tick, I send information from NetLogo to localhost on port 2012 using:
gs:add-sender "sender" "localhost" 2012
I can receive GraphStream in java project:
create instance of CumulativeGraphAnalyser
NetStreamReceiver receiver = new NetStreamReceiver(2012);
new CumulativeGraphAnalyser(receiver, null);
and this is the CumulativeGraphAnalyser class
public class CumulativeGraphAnalyser extends SinkAdapter{
private NetStreamSender sender;
private Graph graph;
private String mySourceId;
private long myTimeId;
private int round;
public CumulativeGraphAnalyser(NetStreamReceiver receiver, NetStreamSender sender) {
this.sender = sender;
graph = new SingleGraph("cumulative graph", false, false);
ProxyPipe pipe = receiver.getDefaultStream();
pipe.addElementSink(graph);
pipe.addElementSink(this);
round = 1;
mySourceId = toString();
myTimeId = 0;
}
#Override
public void stepBegins(String sourceId, long timeId, double step) {
for (Node node : graph.getNodeSet()){
node.getAttribute("node-id");
node.getAttribute("infected");
(...)
}
System.out.println(round++);
}
}
There are all information I need in the 'graph' variable, but I don't know how to save the GraphStream to file (*.gxef) and after that import it in Gephi. The other option is to read the GraphStream in Gephi directly from localhost:2012. I found plugin which suppose to handle this task, but I don't know how to use it properly.
I've searched and read lots of information about this problem, and I've tried to implement some solutions, but none of them doesn't come off.
I'm currently developing a web site using servlets & spring framework. As usual it contains lots of files (jsp, js, css, images, various resources etc).
I'm trying to avoid writing any hardcoded path, or domain in any file ...
For example as you may know when a request is handled you 'forward' it to a jsp page (it's path probably will be hardcoded). Other examples are imports images/css/js etc in jsp files ...
Is there any general way (or tools) to avoid hardcoded paths/urls so any refactorings won't cause troubles?
EDIT
I use netbeans 7.1.2 ... Unfortunately netbeans only helps with pure java code. When working with jsp files things are limited, and if you add custom tag files and Jsp 2.0 EL is like programming in console mode :p
In the JSP files themselves, you can avoid nearly all hardcoded domain / urls by using JSTL
For example, when creating a link to another page, you would do it like this:
Refer an Entrepreneur!
This means that, regardless of where your webapp is, the link will always have the right url. For example, in my development box this link would be:
http://localhost:8080/accounts/referrals/send.html
But on my production server, it resolves correctly to:
http://wwww.mydomain.com/referrals/send.html
You can see that in my dev server, the webapp context is under /accounts, but on the production machine, it's just under / as the webapp is under the root context.
You can read a small tutorial here
Properties file is always a good option so that you have to make changes if any only at one point.
If you are referencing any static contents (js, images, css, etc), you don't have to hardcode the entire file path. Instead, you can do this:-
<img src="${pageContext.request.contextPath}/resources/images/test.jpg"/>
The rest of the file paths (Hibernate domain mappings, forwarded page in Spring controller, etc) should be relative to your project structure, and most IDEs are smart enough to refactor them without problem... or at least in my case, IntelliJ seems to handle of all that for me.
At some point of time, you need to ask yourself, how much of hardcoding is acceptable vs not acceptable? Further, I wouldn't try to stray too far away from the Spring/Hibernate recommended solutions. If you make everything too abstract, you have a different set of problem to deal with and it becomes counterproductive to other peers that may be inheriting your project in the future.
Actually I just came up with an idea. Since netbeans does analysis and shows dependencies on java code, maybe it's better to handle all paths & domains as java variables.
I've created a package on my project named FileResolver and inside I have one class for each file type on my project (eg one class for Jsp files, one for Css files etc). Inside those files I'll record & hardcode all paths of all files in public static final String variables. Sample:
public class Jsps {
public class layouts{
public static final String main = "layouts/main.jsp";
}
public class pages{
public static final String error = "pages/error.jsp";
public static final String login = "pages/login.jsp";
public static final String register = "pages/register.jsp";
}
...
}
All over my project I should use the variables instead of paths. Then anytime I refactor a file, I'll have only one file to change is the mapping value in those variables ...
And if somethime I need to change the variable, netbeans will refactor all of them in the project at once ...
I think this will work just fine since I keep my project clean from file paths and the only thing I have to worry about is the mapping in that file of the variables to appropriate file paths.
EDIT
I'll write a simple parser to create those java files instead of writting by hand for all files ... I'll update when I finish it
UPDATE
Here is my FileResolverGenerator
public class FileResolverGenerator {
private static final String newFilePath = "C:/Users/Foo/Desktop/Jsps.java";
private static final String scanRootFolder = "C:/Users/Foo/Desktop/myProject/web/WEB-INF/jsp";
private static final String varValueReplaceSource = "C:/Users/Foo/Desktop/myProject/web/WEB-INF/jsp/";
private static final String varValueReplaceTarget = "";
private static final boolean valueAlign = true;
private static final int varNameSpaces = 15;
public static void main(String[] args){
try {
// Create file and a writer
File f = new File(newFilePath);
f.createNewFile();
bw = new BufferedWriter( new FileWriter(f) );
// Execute
filesParser( new File(scanRootFolder) );
// 'Burn' file
bw.close();
} catch (FileNotFoundException ex) {
Logger.getLogger(ResolverGenerator.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(ResolverGenerator.class.getName()).log(Level.SEVERE, null, ex);
}
}
// ================================================================================================ //
// ============================================= WORK ============================================= //
// ================================================================================================ //
private static void filesParser(File rootFolder) throws FileNotFoundException, IOException{
folderIn(rootFolder);
// Files first
if(!rootFolder.exists()) throw new FileNotFoundException();
for(File f : rootFolder.listFiles()){
if(f==null){ return; }
if(f.isDirectory()){ continue; }
else if(f.isFile()){ writeFileVariable(f); }
}
// Folders next
for(File f : rootFolder.listFiles()){
if(f==null){ return; }
if(f.isDirectory()){ filesParser(f); }
else if(f.isFile()){ continue; }
}
folderOut(rootFolder);
}
// ================================================================================================ //
// ============================================ PRINTS ============================================ //
// ================================================================================================ //
private static BufferedWriter bw;
private static int tabCount = 0;
private static void folderIn(File f) throws IOException{
bw.append("\n\n");
for(int i=0; i<tabCount; i++)
bw.append("\t");
bw.append("public class "+f.getName()+"{\n");
tabCount++;
}
private static void folderOut(File f) throws IOException{
tabCount--;
for(int i=0; i<tabCount; i++)
bw.append("\t");
bw.append("}\n");
}
private static void writeFileVariable(File f) throws IOException{
String varName = f.getName().split("\\.")[0].replaceAll("-", "");
String varValue = f.getPath().replaceAll("\\\\","/")
.replace(varValueReplaceSource.replaceAll("\\\\","/"),varValueReplaceTarget.replaceAll("\\\\","/"));
for(int i=0; i<tabCount; i++)
bw.append("\t");
bw.append("public static final String "+varName+" = ");
if(valueAlign){
for(int i=0; i<varNameSpaces-varName.length(); i++) bw.append(" ");
bw.append("\t"); }
bw.append("\""+varValue+"\";\n");
}
}
Just to be specific ... This scans all files under "/WEB-INF/jsp/" and creates a java file having all jsp files 'registered' to public static final String variables with each path ... The idea is to use the generated java file as reference for all jsps are in project ... always use these variables instead of hardcoded paths ..
This has nothing to do with the project or any project. It's just a tool which saves you
time, instead of doing this by hand for every file in the project.
I also created another class ResolverConsistencyChecker, which takes all variables and checks if the filepath is correct (file exists) ... since we didn't made any changes to filenames and filepaths all tests are passed.
This method should run when testing project for 'errors'
public class ResolverConsistencyChecker {
private static Class checkClass = Jsps.class;
private static String fullPathPrefix = "C:/Users/Foo/Desktop/myProject/web/WEB-INF/jsp/";
public static void main(String[] args){
try {
filesChecker( checkClass );
System.out.println( "Tests passed. All files locations are valid" );
} catch (FileNotFoundException ex) {
Logger.getLogger(ResolverConsistencyChecker.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(ResolverConsistencyChecker.class.getName()).log(Level.SEVERE, null, ex);
}
}
// ================================================================================================ //
// ============================================= WORK ============================================= //
// ================================================================================================ //
private static void filesChecker(Class rootClass) throws FileNotFoundException, IOException{
// Check file paths in current class depth
for(Field f : rootClass.getFields()){
try {
String fullFilePath = fullPathPrefix+f.get(f.getName()).toString();
File file = new File( fullFilePath );
if( !file.exists() )
throw new FileNotFoundException("Variable: '"+f.getName()+"'\nFile "+fullFilePath);
} catch (IllegalArgumentException ex) {
Logger.getLogger(ResolverConsistencyChecker.class.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
Logger.getLogger(ResolverConsistencyChecker.class.getName()).log(Level.SEVERE, null, ex);
}
}
// Check for embedded classes
for(Class c : rootClass.getClasses()){
filesChecker(c);
}
}
}
I am developing a graphical installer for our application. Since none of the available installer generators meet the requirements and constraints, I am building it from scratch.
The installer is supposed to run on several operating systems, and therefore the path handling needs to be OS-agnostic. I have written the following small utility for this purpose:
public class Path {
private Path() {
}
public static String join(String... pathElements) {
return ListEnhancer.wrap(Arrays.asList(pathElements)).
mkString(File.separator);
}
public static String concatOsSpecific(String path, String element) {
return path + File.separator + element;
}
public static String concatOsAgnostic(String path, String element) {
return path + "/" + element;
}
public static String makeOsAgnostic(String path) {
return path.replace(File.separator, "/");
}
public static String makeOsSpecific(String path) {
return new File(path).getAbsolutePath();
}
public static String fileName(String path) {
return new File(path).getName();
}
}
Now my code is littered with Path.*Agnostic and Path.*Specific calls in many places. As is apparent, this is very error-prone and not transparent at all.
What approach should I take to make the path handling transparent and less error-prone? Do there exist any utilities/libraries that already address this problem? Any help would be greatly appreciated.
EDIT:
To exemplify what I mean, here is some code I wrote a while ago. (Offtopic: Forgive the long-ish method. The code is in initial stages, and will be undergoing some heavy refactoring soon.)
Some context: ApplicationContext is an object that stores the installation data. That includes several paths such as installationRootDirectory, installationDirectory etc. The defaults for these are specified when creating an installer, and hence are always stored in OS-agnostic formats.
#Override
protected void initializeComponents() {
super.initializeComponents();
choosePathLabel = new JLabel("Please select the installation path:");
final ApplicationContext c = installer.getAppContext();
pathTextField = new JTextField(
Path.makeOsSpecific(c.getInstallationDirectory()));
browseButton = new JButton("Browse",
new ImageIcon("resources/images/browse.png"));
browseButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JFileChooser fileChooser = new JFileChooser();
fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
fileChooser.setAcceptAllFileFilterUsed(false);
int choice = fileChooser.showOpenDialog(installer);
String selectedInstallationRootDir = fileChooser.getSelectedFile().
getPath();
if (choice == JFileChooser.APPROVE_OPTION) {
c.setInstallationRootDirectory(
Path.makeOsAgnostic(selectedInstallationRootDir));
pathTextField.setText(Path.makeOsSpecific(c.getInstallationDirectory()));
}
}
});
}
Or you could introduce 2 new classes:
class OsSpecificPath implements FilePathInterface
{
String path;
OsAgnosticPath toAgnosticPath();
OsSpecificPath concat( OsSpecificPath otherPath );
// from IFilePath
getFile();
... etc
}
and
class OsAgnosticPath implements FilePathInterface
{
String path;
OsSpecificPath toOsSpecificPath();
OsAgnosticPath concat( OsAgnosticPath otherPath );
// from IFilePath
getFile();
... etc
}
each wrap a path however they need to.
each method could then have methods to convert to the other type of path, but instead of a "stringly-typed" solution where everything is a string and can be misused, you'd have 2 strongly typed classes that can't be incorrectly passed around.
Anything that doesn't care about the type of path would use FilePathInterface, anything that needs to operate on specific kinds of paths would use those types specificly. FilePathInterface could hypothetically have both toAgnosticPath and toOsSpecificPath in the interface if really necessary...
Not sure if this is what you're going for, but usually when I need to do something path-related in an OS-independent Java program, I always use Strings to pass paths around instead of Files, and I always do the following two things:
Whenever I am building a String path, I always use / as the file separator
Whenever I use a String path to create a File or save it as text somewhere, I always make the following calls prior to using the path:
String fSep = System.getProperty("file.separator);
String path = ... //might be built from scratch, might be passed in from somewhere
path = path.replace("/",fSep).replace("\\",fSep);
This seems to work well regardless of whether the path gets built on the local machine or if it gets passed in from a different machine on the network with a different OS, provided that I intend to use the path on the local machine. If you plan to pass the path between different OS'es via networking, just be careful that your own code is consistent.
EDIT
Wow... somehow my answer got mangled up and the code formatting didn't work as initially intended...
You never need to convert back to os-agnostic. here are the conversions to os-specific:
public class Path {
private Path() {
}
public static String concat(String path, String element) {
return new File(path, element).getPath();
}
public static String makeOsSpecific(String path) {
return new File(path).getAbsolutePath();
}
public static String fileName(String path) {
return new File(path).getName();
}
}
Your sample:
#Override
protected void initializeComponents() {
super.initializeComponents();
choosePathLabel = new JLabel("Please select the installation path:");
final ApplicationContext c = installer.getAppContext();
pathTextField = new JTextField(
Path.makeOsSpecific(c.getInstallationDirectory()));
browseButton = new JButton("Browse",
new ImageIcon("resources/images/browse.png"));
browseButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JFileChooser fileChooser = new JFileChooser();
fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
fileChooser.setAcceptAllFileFilterUsed(false);
int choice = fileChooser.showOpenDialog(installer);
String selectedInstallationRootDir = fileChooser.getSelectedFile().
getPath();
if (choice == JFileChooser.APPROVE_OPTION) {
c.setInstallationRootDirectory(selectedInstallationRootDir);
pathTextField.setText(Path.makeOsSpecific(c.getInstallationDirectory()));
}
}
});
}
I would make my own MyFile object that extends or wraps java.util.File. Then make sure all your code uses this object instead of java.io.File. In here you would be doing the OS checks and calling methods to clean up the file name. The rest of your code would be 'clean'.