I have the following structure:
public class StringFactory {
#Inject
private Instance<StringFormatter> formatterInstances;
#PostConstruct
public void init() {
for (AddressFormatter formatter : formatterInstances) {
System.out.println("String formater: " + formatter);
}
}
}
StringFormatter
interface StringFormatter {
String createFormattedString(final String x);
}
StringFormaterForKR
public class StringFormaterForKR implements StringFormatter {
#Override
public String createFormattedString(String x) {
return null;
}
DefaultStringFormater
public class DefaultStringFormater implements StringFormatter {
#Override
public String createFormattedString(String x) {
return null;
}
Test
public class Test() {
public static void main(String args[]) {
StringFactory factory = new StringFactory();
}
}
I don't understand why formatterInstances is null ?
And I saw that the message from PostConstruct is never printed...
Do you have any explication for this ?
Related
I like to have a Drive class where all files and folders for a project are managed.
My first attempt was pretty easy like a lot of functions (most of them with arguments).
Now I try to make it more fancy because it became more and more annoying to have a lot of functions, in which the desired one can be found. To not have an XY-problem here, I start with my dream.
I like to construct the Drive class in a way, so that it is super easy to find a certain file or folder.
If you look in the main function, I can find every needed file by writing a point and look which subclasses/methods are proposed to continue, till I find it and add .str to it. At every point, only the subclasses/methods will be proposed which makes sense at this point.
It almost works! It is more complicated to write and maintain as the first approach, but If I use it very often, it could be worth it.
I can:
go into subfolders
go into subfolders with name inside the argument
But there is an error if I define a fixed-name-subfolder of a fluid-name-folder like in the code below.
Now my questions:
how can I change the code so the main Function doesn't show this error?
would you recommend a completely different approach to the "make it easy to find strings inside a huge list of strings via making collections inside collections... of strings"-problem?
package utilities;
public class Drive_draft {
private static final String fs = System.getProperty("file.separator");
public static final String str = System.getProperty("user.home").concat(fs);
public static class IeCreation {
public static final String str = Drive_draft.str.concat(".meetings").concat(fs);
public static class Abstract {
public static final String str = IeCreation.str.concat("Abstracts").concat(fs);
}
public static class Meeting {
public static final String str = IeCreation.str.concat("Ueberordnungen").concat(fs);
}
}
public static class MetsSIPs {
public static final String str = Drive_draft.str.concat("workspace").concat(fs).concat("metsSIPs").concat(fs);
public static class preSIPs {
public static final String str = MetsSIPs.str.concat("preSIPs").concat(fs);
}
public static class RosettaInstance {
private static class MaterialflowId {
public static String str;
private static class ProducerId {
public static String str;
private static class Abstract {
public static String str;
public static class Mets {
public static final String str = Abstract.str.concat("content").concat(fs).concat("ie1.xml");
}
}
private static class Meeting {
public static String str;
}
public static Abstract Abstract (String value) {
Abstract ret = new Abstract();
ProducerId.Abstract.str = str.concat(value).concat(fs);
return ret;
}
public static Meeting Meeting (String value) {
Meeting ret = new Meeting();
ProducerId.Meeting.str = str.concat(value).concat(fs);
return ret;
}
}
public static ProducerId ProducerId (String value) {
ProducerId ret = new ProducerId();
MaterialflowId.ProducerId.str = str.concat(value).concat(fs);
return ret;
}
}
public static MaterialflowId MaterialflowId (String value) {
MaterialflowId ret = new MaterialflowId();
MaterialflowId.str = str.concat(value).concat(fs);
return ret;
}
}
public static class Dev extends RosettaInstance {
public static final String str = MetsSIPs.str.concat("dev").concat(fs);
}
public static class Test extends RosettaInstance {
public static final String str = MetsSIPs.str.concat("test").concat(fs);
}
public static class Prod extends RosettaInstance{
public static final String str = MetsSIPs.str.concat("prod").concat(fs);
}
}
#SuppressWarnings("static-access")
public static void main(String[] args) {
System.out.println(Drive_draft.MetsSIPs.Dev.str);
System.out.println(Drive_draft.MetsSIPs.Dev.MaterialflowId("1").str);
System.out.println(Drive_draft.MetsSIPs.Dev.MaterialflowId("2").str);
System.out.println(Drive_draft.MetsSIPs.Dev.MaterialflowId("1").ProducerId("t").str);
System.out.println(Drive_draft.MetsSIPs.Dev.MaterialflowId("1").ProducerId("t").Abstract("est").str);
System.out.println(Drive_draft.MetsSIPs.Dev.MaterialflowId("1").ProducerId("t").Meeting("oast").str);
System.out.println(Drive_draft.MetsSIPs.Dev.MaterialflowId("1").ProducerId("t").Abstract("est").Mets.str); //Error: Mets cannot be resolved or is not a field
}
}
You can encode your "directory" structure with interfaces, with each interface declaring what the user can do next. Then the implementation can use a StringBuilder to just append the appropriate snippets and keep returning this.
// PathBuilderInterfaces.java
public class PathBuilderInterfaces {
public interface Buildable {
String build();
}
public interface Drive extends Buildable {
IeCreation ieCreation();
MetsSIPs metsSIPs();
}
public interface IeCreation extends Buildable {
String ieCreationAbstract();
String meeting();
}
public interface MetsSIPs extends Buildable {
RosettaInstance dev();
RosettaInstance test();
RosettaInstance prod();
}
public interface RosettaInstance extends Buildable {
MaterialFlowId materialFlowId(String value);
}
public interface MaterialFlowId extends Buildable {
ProducerId producerId(String value);
}
public interface ProducerId extends Buildable {
Abstract producerIdAbstract(String value);
String meeting(String value);
}
public interface Abstract extends Buildable {
String mets();
}
}
// PathBuilder.java
import static com.example.somepackage.PathBuilderInterfaces.*;
public class PathBuilder implements Drive, IeCreation, MetsSIPs, RosettaInstance, MaterialFlowId, ProducerId, Abstract{
private StringBuilder builder = new StringBuilder(str);
private static final String fs = System.getProperty("file.separator");
public static final String str = System.getProperty("user.home").concat(fs);
public static Drive drive() {
return new PathBuilder();
}
#Override
public String build() {
return builder.toString();
}
#Override
public IeCreation ieCreation() {
builder.append(".meetings").append(fs);
return this;
}
#Override
public MetsSIPs metsSIPs() {
builder.append("workspace").append(fs).append("metsSIPs").append(fs);
return this;
}
#Override
public RosettaInstance dev() {
builder.append("dev").append(fs);
return this;
}
#Override
public RosettaInstance test() {
builder.append("test").append(fs);
return this;
}
#Override
public RosettaInstance prod() {
builder.append("prod").append(fs);
return this;
}
#Override
public MaterialFlowId materialFlowId(String value) {
builder.append(value).append(fs);
return this;
}
#Override
public ProducerId producerId(String value) {
builder.append(value).append(fs);
return this;
}
#Override
public Abstract producerIdAbstract(String value) {
builder.append(value).append(fs);
return this;
}
#Override
public String meeting(String value) {
builder.append(value).append(fs);
return build();
}
#Override
public String mets() {
builder.append("content").append(fs).append("ie1.xml");
return build();
}
#Override
public String ieCreationAbstract() {
builder.append("Abstracts").append(fs);
return build();
}
#Override
public String meeting() {
builder.append("Ueberordnungen").append(fs);
return build();
}
}
Usage:
// in a main method somewhere
System.out.println(
PathBuilder.drive()
.metsSIPs()
.dev()
.materialFlowId("1")
.producerId("t")
.producerIdAbstract("est")
.mets());
While going through generics, I am not able to understand why the error is coming:
class Box <T> {
private T theThing;
public Box( T t) { theThing = t; }
public void reset( T t) { theThing = t; }
}
class WordBox< S extends CharSequence > extends Box< String > {
public WordBox( S t) { super(t.toString().toLowerCase()); }
public void reset( S t) {
// super.reset(t.toString().toLowerCase());
}
}
public class ss {
public static void main(String[] args) {
WordBox<String> city = new WordBox<String>("Skogland");
city.reset("Stavanger"); // error: ambiguous**
}
}
I can understand, method worldbox.reset () is not overriding the method from BOX, instead it is overloading.
After type erasure, I am assuming this will be code :
class Box {
private Object theThing;
public Box( Object t) { theThing = t; }
public void reset( Object t) { theThing = t; }
}
class WordBox extends Box{
public WordBox( CharSequence t) { super(t.toString().toLowerCase()); }
public void reset( CharSequence t) {
super.reset(t.toString().toLowerCase());
}
}
public class ss {
public static void main(String[] args) {
WordBox<String> city = new WordBox<String>("Skogland");
city.reset("Stavanger");
}
}
So, city.reset("Stavanger") should call the method from Worldbox.reset , as String extends charsequence and it seems to be closest match.
Could anyone please explain why the ambiguous error is coming in this code?
tl;dr;
I am looking for a way to set a "condition" attribute on a Spring Cacheable annotation from another class. Is there such a way?
Using Spring Cache where it should cache ONLY whenever a certain method has been invoked. This method is in ClassA, the method (data) to cache is in ClassB. What I want to do is something like this:
public ClassA implements myInterface {
...
private Boolean inProcess = false;
public void cacheWhenThisMethodCalled() {
try {
inProcess = true;
// do work here, somewhere along the line
// the method in ClassB gets called
} finally {
inProcess = false;
}
}
ClassB:
public ClassB {
...
#Cacheable(cacheNames={"aCache"}, condition="#classA.inProcess")
public ValueClass findValueClass(UUID id)
However, I can't find the right condition for the SPeL to work. I have tried many combinations, none successfully. ClassA is a SpringBean, but the #Bean annotation returns the Interface, not the class. Can this be made to work? Or is there a better way?
Use a ThreadLocal - you would need to do that anyway for thread safety - otherwise a different thread can change the field.
This works fine...
#SpringBootApplication
#EnableCaching
public class So47580936Application {
public static void main(String[] args) {
SpringApplication.run(So47580936Application.class, args);
}
#Bean
public ApplicationRunner runner(Bar bar) {
return args -> {
bar.cacheFromHere();
bar.dontCacheFromHere();
};
}
#Component
public static class Foo {
#Cacheable(cacheNames = "foos", condition = "T(com.example.So47580936Application$Bar).cacheit()")
public String foo() {
System.out.println("here");
return "foo";
}
}
#Component
public static class Bar {
private static final ThreadLocal<Boolean> cacheit = new ThreadLocal<>();
#Autowired
private Foo foo;
public static boolean cacheit() {
return cacheit.get() == null ? false : cacheit.get();
}
public void cacheFromHere() {
try {
this.cacheit.set(true);
System.out.println("Cache:" + this.foo.foo());
System.out.println("Cache:" + this.foo.foo());
}
finally {
this.cacheit.remove();
}
}
public void dontCacheFromHere() {
System.out.println("Don't:" + this.foo.foo());
System.out.println("Don't:" + this.foo.foo());
}
}
}
result:
here
Cache:foo
Cache:foo
here
Don't:foo
here
Don't:foo
EDIT
Or, you can just make the ThreadLocal a #Bean ...
#SpringBootApplication
#EnableCaching
public class So47580936Application {
public static void main(String[] args) {
SpringApplication.run(So47580936Application.class, args);
}
#Bean
public ApplicationRunner runner(Bar bar) {
return args -> {
bar.cacheFromHere();
bar.dontCacheFromHere();
};
}
#Bean
public ThreadLocal<Boolean> cacheit() {
return new ThreadLocal<>();
}
#Component
public static class Foo {
#Cacheable(cacheNames = "foos", condition = "#cacheit.get() ?: false")
public String foo() {
System.out.println("here");
return "foo";
}
}
#Component
public static class Bar {
#Autowired
private ThreadLocal<Boolean> cacheit;
#Autowired
private Foo foo;
public void cacheFromHere() {
try {
this.cacheit.set(true);
System.out.println("Cache:" + this.foo.foo());
System.out.println("Cache:" + this.foo.foo());
}
finally {
this.cacheit.remove();
}
}
public void dontCacheFromHere() {
System.out.println("Don't:" + this.foo.foo());
System.out.println("Don't:" + this.foo.foo());
}
}
}
I am new to jmockit and trying to execute the following online example.
The #MockClass is not working. My BookStore's getBookTitle() method is calling the function of orginal class instead of the mock class.
BookStore class:
public class BookStore {
public String getBookTitle(String isbn){
return BookStoreService.getBookTitle(isbn);
}
}
BookStoreService class:
public class BookStoreService {
public static String getBookTitle(String isbn){
return "Random";
}
}
Test class:
public class BookStoreTest {
private static Map<String, String> bookMap = new HashMap<String, String>(2);
#BeforeClass
public static void setup() {
System.out.println("in setup()");
bookMap.put("0553293354", "Foundation");
bookMap.put("0836220625", "The Far Side Gallery");
}
#MockClass(realClass = BookStoreService.class)
public static class MockBookstoreService {
#Mock
public static String getBookTitle(String isbn) {
System.out.println("in getBookTitle()");
if (bookMap.containsKey(isbn)) {
return bookMap.get(isbn);
} else {
return null;
}
}
}
#Test
public void testGetBookTitle() throws Exception {
System.out.println("in testGetBookTitle()");
final String isbn = "0553293354";
final String expectedTitle = "Foundation";
BookStore store = new BookStore();
String title = store.getBookTitle(isbn);
System.out.println(title); // This prints "Random" instead of "Foundation"
Assert.assertEquals(title, expectedTitle);
}
}
PS: I am using TestNG
Using the latest stable version of jmockit you could do it like this:
#BeforeClass
public static void setup() {
System.out.println("in setup()");
bookMap.put("0553293354", "Foundation");
bookMap.put("0836220625", "The Far Side Gallery");
new MockUp<BookStoreService>() {
#Mock
public String getBookTitle(String isbn) {
System.out.println("in getBookTitle()");
if (bookMap.containsKey(isbn)) {
return bookMap.get(isbn);
} else {
return null;
}
}
};
}
Remove the obsolete block:
public static class MockBookstoreService{...}
i have following code in which the base class Employee have a static method meth1() which i am able to call from a child class (Pro) object . Is it a case of method hiding or what ? , i am not sure because i haven't implemented the meth1() method in Pro class, but still able to call Emplyee static method from Pro object.
class Employee
{
String s;
public String getS() {
return s;
}
public void setS(String s) {
this.s = s;
}
protected static void meth1()
{
System.out.println("inside emp-meth1");
}
}
public class Pro extends Employee {
/*
* public void meth1()
{
System.out.println("inside encapsulation-meth1");
}
*/
public static void main(String as[])
{
Pro e = new Pro();
// e.s ="jay";
e.meth1();
}
}
Output:
inside emp-meth1
Thanks
Jayendra
What are you trying to hide?
Try the below code
emp.meth1() will call method based on reference not based on the object being referred.
class Employee
{
String s;
public String getS() {
return s;
}
public void setS(String s) {
this.s = s;
}
protected static void meth1()
{
System.out.println("inside emp-meth1");
}
}
public class Pro extends Employee {
protected static void meth1()
{
System.out.println("inside encapsulation-meth1");
}
public static void main(String as[])
{
Pro e = new Pro();
Employee emp = new Pro();
emp.meth1(); //this is case of method hiding
e.meth1();
}
}