public interface FileReader {
void readFile();
void writeFile();
}
public class XMLReader implements FileReader {
#Override
public void readFile() {
System.out.println("Hellp i am read");
}
#Override
public void writeFile() {
System.out.println("Hello i am write");
}
}
public class ExcelReader implements FileReader {
#Override
public void readFile() {
System.out.println("Hellp i am read");
}
#Override
public void writeFile() {
System.out.println("Hello i am write");
}
}
public class Context {
FileReader reader ;
public Context(FileReader reader) {
super();
this.reader = reader;
}
public void executeRead(){
reader.readFile();
}
}
public class TestStrategy {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println(args[0]);
String s=args[0];
String[] a=s.split("\\.");
if(a[1].equals("csv")){
new Context(new XMLReader()).executeRead();
}else{
new Context(new ExcelReader()).executeRead();
}
}
}
I have a concern more file format are introduced we will create separate class for them but i have to change the if else code in TestStrategy class to create new object for the file pattern introduced.
Can we remove this if else code .Any suggestions.
You could use a registry that maps a files extension to the implementation.
public class Registry {
static Map<String,FileReader> reg = new HashMap<String,FileReader>();
public static void register(String ext, FileReader fr ) {
reg.put( ext, fr );
}
}
and let newly added implementation register themself e.g.
public class XMLReader implements FileReader {
static {
Registry.register( "xml", new XMLReader() );
}
....
public class ExcelReader implements FileReader {
static {
Registry.register( "xls", new ExcelReader() );
}
...
then you could simply lookup the registry for a suitable implementation with no if or switch required.
You can get a class by name. Build a Map to configure the FileReader to use for each extension.
public static void main(String[] args)
throws ClassNotFoundException, InstantiationException, IllegalAccessException {
Map<String, String> extensionToClass = new HashMap<>();
extensionToClass.put("xml", "de.lhorn.XMLReader");
extensionToClass.put("xls", "de.lhorn.ExcelReader");
String s = "foo.xml";
String[] a = s.split("\\.");
String extension = a[1];
// Get the class that is configured for the extension.
String className = extensionToClass.get(extension);
Class clazz = Class.forName(className);
// Create a new instance of this class.
FileReader reader = (FileReader) clazz.newInstance();
// Use the FileReader.
new Context(reader).executeRead();
}
You can read extensionToClass from an external source, of course.
Related
In my project, I have a method which loads a big model from local disk. Loading the model takes about 15 minutes and sometimes more. What i'm thinking to do is to create a runnable method which loads the model for once and then, from different classes i call this method to execute some code.
in fact, i'm not sure how to achieve that, could you please guide me?
Here is simple pseudo code:
// class A has two method , load the model , and does some calculation
Class A: 1.Runnable method: LoadModel();
2.Mehtod2: distance();
// here i would like to run this programe anytime, pass some parameters and call the method "distance" in class A
Class B: 1.import Loadmodel() class and invoke distance ();
in my mind i'd like to create something similar to server but not server:)
Updated:The code below is what I've tried so far.
public class load implements Runnable {
WordVectors wordVectors;
public void run() {
try {
load();
} catch (FileNotFoundException ex) {
java.util.logging.Logger.getLogger(load.class.getName()).log(Level.SEVERE, null, ex);
} catch (UnsupportedEncodingException ex) {
java.util.logging.Logger.getLogger(load.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void load() throws FileNotFoundException, UnsupportedEncodingException {
//Your display method implementation.
wordVectors = WordVectorSerializer.loadTxtVectors(new File("glove.twitter.27B.200d.txt"));
}
public double Simmiraty(String a, String b){
return wordVectors.similarity(a,b);
}
public static void main(String[] args) {
load Obj= new load ();
Obj.run();
}
}
The Second class:
public class B{
public static void main(String[] args) throws Exception {
load ob =new load();
System.out.println( ob.Simmiraty("iphone", "battery"));
}
}
I have to prolem with the above code:
1. it stops running once it has loaded the model.
2. I can't invoke any method from the frist class.
public class Load implements Runnable{
private InputStream stream;
private static final Load instance;
private WordVectors wordVectors;
static {
instance = new Load();
instance.run();
}
public static Load GetLoad(){
return instance;
}
private Load(){
if(instance != null)
throw new UnsupportedOperationException();
}
public voir run() {
if(wordVectors != null)
throw new UnsupportedOperationException();
try {
load();
} catch (Exception ex) {
Logger.getLogger(load.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void load() throws FileNotFoundException, UnsupportedEncodingException {
stream = new InputStream(new File("glove.twitter.27B.200d.txt"));
wordVectors = WordVectorSerializer.loadTxtVectors(stream,false);
}
public void interrupt(){
if(stream != null)
stream.close();
}
public double Simmiraty(String a, String b){
return wordVectors.similarity(a,b);
}
public static void main(){
Load load = GetLoad();
}
}
public class B{
public void function(){
Load load = Load.GetLoad();
}
}
I'm working on an university homework and we have to use hadoop mapreduce for it. I'm trying to create a new custom writable as I want to output key-value pairs as (key, (doc_name, 1)).
public class Detector {
private static final Path TEMP_PATH = new Path("temp");
private static final String LENGTH = "gramLength";
private static final String THRESHOLD = "threshold";
public class Custom implements Writable {
private Text document;
private IntWritable count;
public Custom(){
setDocument("");
setCount(0);
}
public Custom(String document, int count) {
setDocument(document);
setCount(count);
}
#Override
public void readFields(DataInput in) throws IOException {
// TODO Auto-generated method stub
document.readFields(in);
count.readFields(in);
}
#Override
public void write(DataOutput out) throws IOException {
document.write(out);
count.write(out);
}
public int getCount() {
return count.get();
}
public void setCount(int count) {
this.count = new IntWritable(count);
}
public String getDocument() {
return document.toString();
}
public void setDocument(String document) {
this.document = new Text(document);
}
}
public static class NGramMapper extends Mapper<Text, Text, Text, Text> {
private int gramLength;
private Pattern space_pattern=Pattern.compile("[ ]");
private StringBuilder gramBuilder= new StringBuilder();
#Override
protected void setup(Context context) throws IOException, InterruptedException{
gramLength=context.getConfiguration().getInt(LENGTH, 0);
}
public void map(Text key, Text value, Context context) throws IOException, InterruptedException {
String[] tokens=space_pattern.split(value.toString());
for(int i=0;i<tokens.length;i++){
gramBuilder.setLength(0);
if(i+gramLength<=tokens.length){
for(int j=i;j<i+gramLength;j++){
gramBuilder.append(tokens[j]);
gramBuilder.append(" ");
}
context.write(new Text(gramBuilder.toString()), key);
}
}
}
}
public static class OutputReducer extends Reducer<Text, Text, Text, Custom> {
public void reduce(Text key, Iterable<Text> values, Context context)
throws IOException, InterruptedException {
for (Text val : values) {
context.write(key,new Custom(val.toString(),1));
}
}
}
public static void main(String[] args) throws Exception {
Configuration conf = new Configuration();
FileSystem fs = FileSystem.get(conf);
conf.setInt(LENGTH, Integer.parseInt(args[0]));
conf.setInt(THRESHOLD, Integer.parseInt(args[1]));
// Setup first MapReduce phase
Job job1 = Job.getInstance(conf, "WordOrder-first");
job1.setJarByClass(Detector.class);
job1.setMapperClass(NGramMapper.class);
job1.setReducerClass(OutputReducer.class);
job1.setMapOutputKeyClass(Text.class);
job1.setMapOutputValueClass(Text.class);
job1.setOutputKeyClass(Text.class);
job1.setOutputValueClass(Custom.class);
job1.setInputFormatClass(WholeFileInputFormat.class);
FileInputFormat.addInputPath(job1, new Path(args[2]));
FileOutputFormat.setOutputPath(job1, new Path(args[3]));
boolean status1 = job1.waitForCompletion(true);
if (!status1) {
System.exit(1);
}
}
}
When I compile the code to a class file i get this error:
Detector.java:147: error: non-static variable this cannot be referenced from a static context
context.write(key,new Custom(val.toString(),1));
I followed differents tutorials about custom writable and my solution is the same as the others. Any suggestion?
Static fields and methods are shared with all instances. They are for values which are specific to the class and not a specific instance. Stay out of them as much as possible.
To solve your problem, you need to instantiate an instance (create an object) of your class so the run-time can reserve memory for the instance; or change the part you are accessing it to have static access (not recommended!).
The keyword this is for referencing something that's indeed an instance (hence the this thing) and not something that's static, which in that case should be referenced by the class name instead. You are using it in a static context which is not allowed.
I have a text file which contains the list of all public method names. I require a Java program which reads each method name from the text file and create a method(template) for each public method name.
Say,
My text file contains, 3 methods
public static void A()
public static void B()
public static void C()
I need a output like this.
public class class_name
{
public void A_test()
{
System.out.println("Method A");
}
public void B_test()
{
System.out.println("Method B");
}
public void C_test()
{
System.out.println("Method C");
}
}
Kindly give your suggestions.
Following your example above the code below will generate a similar output. Note there is no package. NOTE As your example the generator strips static
public class ClassBuilder
{
public static String buildClass(String className,ArrayList<String> methods)
{
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(String.format("public class %s \n{", className)).append("\n");
for (String method: methods)
{
stringBuilder.append(String.format(" %s \n {", method.trim().replace("static ","").replace("()","_test()"))).append("\n }\n\n");
}
stringBuilder.append("}");
return stringBuilder.toString();
}
public static void main(String[] args)
{
Scanner scanner = null;
try
{
scanner = new Scanner(new File("d:\\testFile.txt"));
ArrayList<String> methods = new ArrayList<String>();
while (scanner.hasNext())
{
methods.add(scanner.nextLine());
}
scanner.close();
String javaClass = buildClass("className", methods);
System.out.println(javaClass);
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
}
}
output
public class className
{
public void A_test()
{
}
public void B_test()
{
}
public void C_test()
{
}
}
I'd like to change from which .properties file class should get them.
My class is like this now:
public class MyClass {
private String str;
public MyClass() throws IOException {
loadProperties();
}
private void loadProperties() throws IOException {
Properties props = new Properties();
props.load(getClass().getClassLoader().getResourceAsStream("my.properties"));
str= props.getProperty("property");
}
And whyle testing i would like properties to be loaded from another file.
It's apache camel app, so i have this now:
public class ConverterTest {
#Override
protected RouteBuilder createRouteBuilder() throws Exception {
return new MyClass(); //--> Here i must load from another file
}
#Test
// test
}
Can this be achieved?
Just pass property file name to MyClass constructor
public MyClass(String propsFile) throws IOException {
loadProperties(propsFile);
}
There is something you can do:
public class MyClass {
private String str;
private String path = "my.properties";
public MyClass() throws IOException {
loadProperties();
}
protected void loadProperties() throws IOException {
Properties props = new Properties();
props.load(getClass().getClassLoader().getResourceAsStream(path));
str= props.getProperty("property");
}
And then, add a test to the same package with the code:
myClass = new MyClass();
ReflectionTestUtils.setField(path, "otherpathto.properties");
myClass.loadProperties();
It involves a small change in the code, but it might not be a big deal... depending on your project.
Arguably the cleanest solution would be to refactor MyClass and remove dependency on Properties object and inject the values needed via the constructor instead. Your case proves that hidden and hardcoded dependencies complicate testing.
Responsibility for reading the properties file and injecting the value into MyClass could be pushed back to its caller:
public class MyClass {
private final String str;
public MyClass(String strValue) {
this.str = strValue;
}
// ...
}
public class ProductionCode {
public someMethod() {
Properties props = new Properties();
props.load(getClass().getClassLoader().getResourceAsStream("my.properties"));
String str = props.getProperty("property");
MyClass obj = new MyClass(str);
obj.foo();
}
}
public class ConverterTest {
#Test
public void test() {
String testStr = "str for testing";
MyClass testee = new MyClass(testStr);
testee.foo();
// assertions
}
}
Need to create a class that i can load properties in and be able to call required properties from that class. such as propertiesClass.getname();
Here's my Class so far. I can't seem to initiate the property load.
So what i need is from another class in the project to just do (currently getting null)
String url = TestProperties.getBaseUrl();
*updated the class, here's what it looks like now.
public class TestProperties {
private static Properties testProperties;
private static String instanceUrl;
public TestProperties() throws Exception{
loadProperties();
getInstanceProperties();
instanceUrl = TestProperties.testProperties.getProperty("confluence.base.url","");
}
public static String getBaseUrl(){
return instanceUrl;
}
private void loadProperties() throws IOException {
InputStream testPropertiesInput = this.getClass().getClassLoader().getResourceAsStream("smoketest.properties");
TestProperties.testProperties = new Properties();
// if (null != testProperties) {
try{
TestProperties.testProperties.load(testPropertiesInput);
} finally {
IOUtils.closeQuietly(testPropertiesInput);
}
// }
}
}
my otherclass(){
String myurl = TestProperties.getBaseUrl();
}
The method
public void TestProperties() throws Exception{
was meant to be constructor but isn't one, so the class only gets a default no-arg constructor. Change that to:
public TestProperties() throws Exception{
i.e. remove the return type as constructors are distinguished from ordinary methods by not declaring a return type.
Please make sure you are able to rightly access your properties file smoketest.properties though InputStream testPropertiesInput.
EDIT:
There is no need to redefine the local variable in loadProperties and return it. It can be written very simply as:
private static void loadProperties() throws IOException {
InputStream testPropertiesInput = getClass().getClassLoader()
.getResourceAsStream("smoketest.properties");
Properties testProperties = new Properties();
try{
TestProperties.testProperties.load(testPropertiesInput);
} finally {
IOUtils.closeQuietly(testPropertiesInput);
}
TestProperties.testProperties = testProperties;
}
I think public void TestProperties() throws Exception{ is constructor of your class. If yes, please remove void from it as it making it as a method.
Finally you may want to use testProperties in your TestProperties() constructor as :
public TestProperties() throws Exception{
loadProperties();
getInstanceProperties();
instanceUrl = TestProperties.testProperties
.getProperty("confluence.base.url","");
}
Please Note: I don't think your class variables should be defined as static. Is there any reason of doing so?
EDIT: Here is the hopefully working sample code for you:
public class TestProperties {
private static Properties testProperties;
private static String instanceUrl;
public TestProperties(){
try{
loadProperties();
//getInstanceProperties();
instanceUrl = TestProperties.testProperties
.getProperty("confluence.base.url","");
}catch(IOException ioe){
ioe.printStackTrace();
}
}
static{
//Just to initialize the properties
new TestProperties();
}
private void loadProperties() throws IOException {
InputStream testPropertiesInput = getClass().getClassLoader()
.getResourceAsStream("smoketest.properties");
Properties testProperties = new Properties();
try{
testProperties.load(testPropertiesInput);
} finally {
IOUtils.closeQuietly(testPropertiesInput);
}
TestProperties.testProperties = testProperties;
}
public static String getBaseUrl(){
return instanceUrl;
}
public static String getPropertyValue(String key){
return TestProperties.testProperties.getProperty(key,"Not Found");
}
}
Now you can simply get your base URL any where as :
public static void main(String[] args) {
System.out.println(TestProperties.getBaseUrl());
System.out.println(TestProperties.getPropertyValue("confluence.base.url"));
System.out.println(TestProperties.getPropertyValue("test.property"));
}