Getting variables from another .java file using reflection - java

I've managed to get reflection working by getting and formatting the variables in the class that the toString() method is in.
public class ReadFile {
public int test1 =0;
public String test2 = "hello";
Boolean test3 = false;
int test4 = 1;
public static void main(String[] args) throws IOException{
ReadFile test = new ReadFile();
System.out.println(test);
}
public String toString(){
//Make a string builder so we can build up a string
StringBuilder result = new StringBuilder();
//Declare a new line constant
final String NEW_LINE = System.getProperty("line.separator");
//Gets the name of THIS Object
result.append(this.getClass().getName() );
result.append(" Class {" );
result.append(NEW_LINE);
//Determine fields declared in this class only (no fields of superclass)
Field[] fields = this.getClass().getDeclaredFields();
//Print field names paired with their values
for ( Field field : fields ) {
result.append(" ");
try {
result.append(field.getType() + " ");
result.append( field.getName() );
result.append(": ");
//requires access to private field:
result.append( field.get(this) );
} catch ( IllegalAccessException ex ) {
System.out.println(ex);
}
result.append(NEW_LINE);
}
result.append("}");
return result.toString();
}
}
However I was wondering whether it would be possible to specify a specific file in the directory for the toString() to work on?
I have tried getting a file and plugging it in the System.out.println() but the way I see it is you need to make an instance of a class and give it the instance for it to work. So I'm not sure how that can be done programatically.
I have been trying something like this:
Path path = FileSystems.getDefault().getPath("D:\\Directory\\Foo\\Bar\\Test.java", args);
File file = path.toFile();
System.out.println(file);
However I don't get very far with it, I've mainly been seeing if I can convert the file into anything usable but I'm not sure what I need to be doing!
Any advice would be great.

I think you need to look into the ClassLoader API - you need to get an new URLClassLoader and ask it to load your .java file into the JVM. You can then reflect on it.

You can try to read the package information from the file (D:\Directory\Foo\Bar\Test.java) and than try to load it the class by its name:
Class.forName(nameOfTheClass)
Java API Class

Related

Accessing Object Property for Individual using Apache Jena

I have created an OWL ontology using Protégé, describing a patient database system. I am now attempting to develop a Java code using Apache Jena to read the OWL file I created, then perform a number of operations on it. My primary goal is to get my code to be able to find a specific Individual by name (Patient name for example) and then access a specific Object Property for that individual, and output its value. For example, A patient "John" has an object property "Treated_By" which corresponds to another individual "Amy" (Amy is an individual of type doctor). However, I have been unable to figure out which Jena method is used to retrieve Object property values from a certain individual.
Here is my code (Please ignore comments, they are fragments of previous attempts for this task):
public class Main {
public static void main(String[] args) {
OntModel model = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
String fileName = "C:/Users/Ahmed Medhat/Documents/assignment1ontv3.0.owl";
try {
InputStream inputStream = new FileInputStream(fileName);
model.read(inputStream, "RDF/XML");
//model.read(inputStream, "OWL/XML");
inputStream.close();
} catch (Exception e) {
System.out.println(e.getMessage());
}
Scanner sc = new Scanner(System.in);
System.out.println("Enter Patient Name: ");
String patientName = sc.next();
ExtendedIterator<Individual> itI = model.listIndividuals();
while (itI.hasNext()) {
Individual i = itI.next();
String localName = i.getLocalName();
//System.out.println(patientName);
//System.out.println(localName);
if(localName.equals(patientName))
{
//System.out.println("Conditional Code Accessed.");
OntClass Class = i.getOntClass();
System.out.println("Patient Disease is: " + Class.listDeclaredProperties());
}
System.out.println("Failed.");
}
}
}
Try this (replace the property URI accordingly):
final Property p = model.createObjectProperty("http://example.org/Treated_by");
final RDFNode object = i.getPropertyValue(p);

Java: ClassNotFound Classpath issues

Im trying to read some information from a file into some objects. Main method just reads the Information into some string variables then uses those strings to initialize objects. Pretty simple. The objects are stored using a BST.
However, The error Im getting is ClassNotFoundException. Except when I run the java 'file' command, 'file' is spelled and capitalized correctly.
I've been reading that you can change the path that JVM uses when searching for class files.
so I tried:
set CLASSPATH=$CLASSPATH=~/../../BackEnd
but that didn't do anything..
Here is my main file..
import java.util.Scanner;
import java.io.File;
class BackEnd
{
public static void main(String args[]) throws java.io.FileNotFoundException
{
Tree.ServiceTree providers = new Tree.ServiceTree();
String path = "./providers.txt";
Scanner read = new Scanner (new File(path));
read.useDelimiter(",");
String information[] = new String[5];//array of strings used to store info from file, then used to initialize objects
try
{
while(read.hasNext())
{
for(int i = 0; i < 5; ++i)
{
information[i] = read.nextLine();//read in all the info into the array
}
Services.Service newService;//used as dynamic reference to be passed to tree
Services.Service serviceInfo = new Services.Service(information[0], information[1]);//initalizes base class to be passed to derived constructor
switch(information[0])//check type to initalize appropriate object
{
case "Dogwalk":
newService = new Services.Dogwalk(serviceInfo, information[2], information[3]);
case "Groceries":
newService = new Services.Groceries(serviceInfo, information[2], information[3]);
case "Housework":
newService = new Services.Housework(serviceInfo, information[2], information[3]);
}
providers.insert(information[4], newService);
}
read.close();
throw new java.io.FileNotFoundException("File not found...");
}
catch(java.io.FileNotFoundException exception)
{
System.out.println("File not found");
}
//providers.display();
}
}
Figured it out. Error had nothing to do with compilation or class path and was due
to uninitialized variable newService

How can I read Class and objects name from File using Java Reflection?

I have a file named Objects.dat and I want to read the Class name and objects name from that file using Java Reflection. I'm able to read from another Java class but not from the file. How can I solve this?
Java Class
public class EmployeeInfo {
private String username = "John";
private int userage = 23;
}
Objects.dat contains the same text as Java class.
Class Reader
public class FileRd {
public static void main(String[] args) {
try {
Class cls = Class.forName("EmployeeInfo");
Object obj = cls.newInstance();
System.out.println("Class Name-->"+obj.getClass());
Field[] fields = cls.getDeclaredFields();
for( int i = 0 ; i < fields.length ; i++ ) {
fields[i].setAccessible(true);
System.out.println("Name-->"+fields[i].getName());
}
}
catch( Exception e ) { e.printStackTrace(); }
}
}
The above code works for the Java class but I want to input the file like and read -
FileInputStream fin = new FileInputStream("D:\\Objects.bat");
and perform the above functionally but I failed to do that.
You need a Custom classloader for such, if the file is already compiled (if not you can use javac tool to compile it with classpath or an Bytecode tool like ASM or Javassist).
Then you use your ClassLoader to load the file(.class) and findClass.
Maybe Serialization / Deserialization is the better way than save Java code at the file.

Implementing save/open with RichTextFX?

Here is my code:
private void save(File file) {
StyledDocument<ParStyle, Either<StyledText<TextStyle>, LinkedImage<TextStyle>>, TextStyle> doc = textarea.getDocument();
// Use the Codec to save the document in a binary format
textarea.getStyleCodecs().ifPresent(codecs -> {
Codec<StyledDocument<ParStyle, Either<StyledText<TextStyle>, LinkedImage<TextStyle>>, TextStyle>> codec
= ReadOnlyStyledDocument.codec(codecs._1, codecs._2, textarea.getSegOps());
try {
FileOutputStream fos = new FileOutputStream(file);
DataOutputStream dos = new DataOutputStream(fos);
codec.encode(dos, doc);
fos.close();
} catch (IOException fnfe) {
fnfe.printStackTrace();
}
});
}
I am trying to implement the save/loading from the demo from here on the RichTextFX GitHub.
I am getting errors in the following lines:
StyledDocument<ParStyle, Either<StyledText<TextStyle>, LinkedImage<TextStyle>>, TextStyle> doc = textarea.getDocument();
error: incompatible types:
StyledDocument<Collection<String>,StyledText<Collection<String>>,Collection<String>>
cannot be converted to
StyledDocument<ParStyle,Either<StyledText<TextStyle>,LinkedImage<TextStyle>>,TextStyle>
and
= ReadOnlyStyledDocument.codec(codecs._1, codecs._2, textarea.getSegOps());
error: incompatible types: inferred type does not conform to equality
constraint(s) inferred: ParStyle
equality constraints(s): ParStyle,Collection<String>
I have added all the required .java files and imported them into my main code. I thought it would be relatively trivial to implement this demo but it has been nothing but headaches.
If this cannot be resolved, does anyone know an alternative way to save the text with formatting from RichTextFX?
Thank you
This question is quite old, but since i ran into the same problem i figured a solution might be useful to others as well.
In the demo, the code from which you use, ParStyle and TextStyle (Custom Types) are used for defining how information about the style is stored.
The error messages you get pretty much just tell you that your way of storing the information about the style (In your case in a String) is not compatible with the way it is done in the demo.
If you want to store the style in a String, which i did as well, you need to implement some way of serializing and deserializing the information yourself.
You can do that, for example (I used an InlineCssTextArea), in the following way:
public class SerializeManager {
public static final String PAR_REGEX = "#!par!#";
public static final String PAR_CONTENT_REGEX = "#!pcr!#";
public static final String SEG_REGEX = "#!seg!#";
public static final String SEG_CONTENT_REGEX = "#!scr!#";
public static String serialized(InlineCssTextArea textArea) {
StringBuilder builder = new StringBuilder();
textArea.getDocument().getParagraphs().forEach(par -> {
builder.append(par.getParagraphStyle());
builder.append(PAR_CONTENT_REGEX);
par.getStyledSegments().forEach(seg -> builder
.append(
seg.getSegment()
.replaceAll(PAR_REGEX, "")
.replaceAll(PAR_CONTENT_REGEX, "")
.replaceAll(SEG_REGEX, "")
.replaceAll(SEG_CONTENT_REGEX, "")
)
.append(SEG_CONTENT_REGEX)
.append(seg.getStyle())
.append(SEG_REGEX)
);
builder.append(PAR_REGEX);
});
String textAreaSerialized = builder.toString();
return textAreaSerialized;
}
public static InlineCssTextArea fromSerialized(String string) {
InlineCssTextArea textArea = new InlineCssTextArea();
ReadOnlyStyledDocumentBuilder<String, String, String> builder = new ReadOnlyStyledDocumentBuilder<>(
SegmentOps.styledTextOps(),
""
);
if (string.contains(PAR_REGEX)) {
String[] parsSerialized = string.split(PAR_REGEX);
for (int i = 0; i < parsSerialized.length; i++) {
String par = parsSerialized[i];
String[] parContent = par.split(PAR_CONTENT_REGEX);
String parStyle = parContent[0];
List<String> segments = new ArrayList<>();
StyleSpansBuilder<String> spansBuilder = new StyleSpansBuilder<>();
String styleSegments = parContent[1];
Arrays.stream(styleSegments.split(SEG_REGEX)).forEach(seg -> {
String[] segContent = seg.split(SEG_CONTENT_REGEX);
segments.add(segContent[0]);
if (segContent.length > 1) {
spansBuilder.add(segContent[1], segContent[0].length());
} else {
spansBuilder.add("", segContent[0].length());
}
});
StyleSpans<String> spans = spansBuilder.create();
builder.addParagraph(segments, spans, parStyle);
}
textArea.append(builder.build());
}
return textArea;
}
}
You can then take the serialized InlineCssTextArea, write the resulting String to a file, and load and deserialize it.
As you can see in the code, i made up some Strings as regexes which will be removed in the serialization process (We don't want our Serializer to be injectable, do we ;)).
You can change these to whatever you like, just note they will be removed if used in the text of the TextArea, so they should be something users wont miss in their TextArea.
Also note that this solution serializes the Style of the Text, the Text itself and the Paragraph style, BUT not inserted images or parameters of the TextArea (such as width and height), just the text content of the TextArea with its Style.
This issue on github really helped me btw.

What is the best way to generate a unique and short file name in Java

I don't necessarily want to use UUIDs since they are fairly long.
The file just needs to be unique within its directory.
One thought which comes to mind is to use File.createTempFile(String prefix, String suffix), but that seems wrong because the file is not temporary.
The case of two files created in the same millisecond needs to be handled.
Well, you could use the 3-argument version: File.createTempFile(String prefix, String suffix, File directory) which will let you put it where you'd like. Unless you tell it to, Java won't treat it differently than any other file. The only drawback is that the filename is guaranteed to be at least 8 characters long (minimum of 3 characters for the prefix, plus 5 or more characters generated by the function).
If that's too long for you, I suppose you could always just start with the filename "a", and loop through "b", "c", etc until you find one that doesn't already exist.
I'd use Apache Commons Lang library (http://commons.apache.org/lang).
There is a class org.apache.commons.lang.RandomStringUtils that can be used to generate random strings of given length. Very handy not only for filename generation!
Here is the example:
String ext = "dat";
File dir = new File("/home/pregzt");
String name = String.format("%s.%s", RandomStringUtils.randomAlphanumeric(8), ext);
File file = new File(dir, name);
I use the timestamp
i.e
new File( simpleDateFormat.format( new Date() ) );
And have the simpleDateFormat initialized to something like as:
new SimpleDateFormat("File-ddMMyy-hhmmss.SSS.txt");
EDIT
What about
new File(String.format("%s.%s", sdf.format( new Date() ),
random.nextInt(9)));
Unless the number of files created in the same second is too high.
If that's the case and the name doesn't matters
new File( "file."+count++ );
:P
This works for me:
String generateUniqueFileName() {
String filename = "";
long millis = System.currentTimeMillis();
String datetime = new Date().toGMTString();
datetime = datetime.replace(" ", "");
datetime = datetime.replace(":", "");
String rndchars = RandomStringUtils.randomAlphanumeric(16);
filename = rndchars + "_" + datetime + "_" + millis;
return filename;
}
// USE:
String newFile;
do{
newFile=generateUniqueFileName() + "." + FileExt;
}
while(new File(basePath+newFile).exists());
Output filenames should look like :
2OoBwH8OwYGKW2QE_4Sep2013061732GMT_1378275452253.Ext
Look at the File javadoc, the method createNewFile will create the file only if it doesn't exist, and will return a boolean to say if the file was created.
You may also use the exists() method:
int i = 0;
String filename = Integer.toString(i);
File f = new File(filename);
while (f.exists()) {
i++;
filename = Integer.toString(i);
f = new File(filename);
}
f.createNewFile();
System.out.println("File in use: " + f);
If you have access to a database, you can create and use a sequence in the file name.
select mySequence.nextval from dual;
It will be guaranteed to be unique and shouldn't get too large (unless you are pumping out a ton of files).
//Generating Unique File Name
public String getFileName() {
String timeStamp = new SimpleDateFormat("yyyy-MM-dd_HH:mm:ss").format(new Date());
return "PNG_" + timeStamp + "_.png";
}
I use current milliseconds with random numbers
i.e
Random random=new Random();
String ext = ".jpeg";
File dir = new File("/home/pregzt");
String name = String.format("%s%s",System.currentTimeMillis(),random.nextInt(100000)+ext);
File file = new File(dir, name);
Combining other answers, why not use the ms timestamp with a random value appended; repeat until no conflict, which in practice will be almost never.
For example: File-ccyymmdd-hhmmss-mmm-rrrrrr.txt
Why not just use something based on a timestamp..?
Problem is synchronization. Separate out regions of conflict.
Name the file as : (server-name)_(thread/process-name)_(millisecond/timestamp).(extension)
example : aws1_t1_1447402821007.png
How about generate based on time stamp rounded to the nearest millisecond, or whatever accuracy you need... then use a lock to synchronize access to the function.
If you store the last generated file name, you can append sequential letters or further digits to it as needed to make it unique.
Or if you'd rather do it without locks, use a time step plus a thread ID, and make sure that the function takes longer than a millisecond, or waits so that it does.
It looks like you've got a handful of solutions for creating a unique filename, so I'll leave that alone. I would test the filename this way:
String filePath;
boolean fileNotFound = true;
while (fileNotFound) {
String testPath = generateFilename();
try {
RandomAccessFile f = new RandomAccessFile(
new File(testPath), "r");
} catch (Exception e) {
// exception thrown by RandomAccessFile if
// testPath doesn't exist (ie: it can't be read)
filePath = testPath;
fileNotFound = false;
}
}
//now create your file with filePath
This also works
String logFileName = new SimpleDateFormat("yyyyMMddHHmm'.txt'").format(new Date());
logFileName = "loggerFile_" + logFileName;
I understand that I am too late to reply on this question. But I think I should put this as it seems something different from other solution.
We can concatenate threadname and current timeStamp as file name. But with this there is one issue like some thread name contains special character like "\" which can create problem in creating file name. So we can remove special charater from thread name and then concatenate thread name and time stamp
fileName = threadName(after removing special charater) + currentTimeStamp
Why not use synchronized to process multi thread.
here is my solution,It's can generate a short file name , and it's unique.
private static synchronized String generateFileName(){
String name = make(index);
index ++;
return name;
}
private static String make(int index) {
if(index == 0) return "";
return String.valueOf(chars[index % chars.length]) + make(index / chars.length);
}
private static int index = 1;
private static char[] chars = {'a','b','c','d','e','f','g',
'h','i','j','k','l','m','n',
'o','p','q','r','s','t',
'u','v','w','x','y','z'};
blew is main function for test , It's work.
public static void main(String[] args) {
List<String> names = new ArrayList<>();
List<Thread> threads = new ArrayList<>();
for (int i = 0; i < 100; i++) {
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
for (int i = 0; i < 1000; i++) {
String name = generateFileName();
names.add(name);
}
}
});
thread.run();
threads.add(thread);
}
for (int i = 0; i < 10; i++) {
try {
threads.get(i).join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(names);
System.out.println(names.size());
}

Categories