Passing a value between classes - java

I need to pass a string from class to another class in Java (Bukkit), I have already read some similar questions, but I can't solve the problem.
I have a Main class
public class Main extends JavaPlugin {
#Override
public void onEnable() {
new PlayerListener(this);
this.saveDefaultConfig();
String bannedBlocksString = this.getConfig().getString("bannedBlocks");
}
#Override
public void onDisable() {
}
}
And another class "PlayerListener"
public class PlayerListener implements Listener {
public PlayerListener(Main plugin) {
plugin.getServer().getPluginManager().registerEvents(this, plugin);
}
// public static final String bannedBlocksString = "DIAMOND_BLOCK; EMERALD_BLOCK";
public static final String[] bannedBlocks = bannedBlocksString.split("; ");
public static boolean isBannedBlock(String[] bannedBlocks, String blockPlaced) {
boolean returnValue = false;
for (String bannedBlock : bannedBlocks) {
if(blockPlaced.equalsIgnoreCase(bannedBlock)){
returnValue = true;
}
}
return returnValue;
}
#EventHandler
public void onBlockPlace(BlockPlaceEvent event) {
String blockPlaced = event.getBlockPlaced().getType().toString();
if(!event.getPlayer().hasPermission("antibuild.block.noplace") && isBannedBlock(bannedBlocks, blockPlaced)) {
event.setCancelled(true);
event.getPlayer().sendMessage(ChatColor.RED + "You can not place this block.");
}
}
}
How can I get the value of bannedBlocksString in Main from the class "PlayerListener"?

Try this, I hope it works:
From Main:
PlayerListener pl = new PlayerListener(this);
this.saveDefaultConfig();
String [] bannedBlocksString = pl.getBannedBlocks();
From PlayerListener you have to declare get method:
public String [] getBannedBlocks(){
return this.bannedBlocks;
}

If you uncomment the bannedBlocksString in the PlayerListener then you can always access it in the Main class using PlayerListener.bannedBlocksString as the variable is static.
If you want to do it the other way arround and assign the value you need to remove the final from the variable and use the code beneath.
PlayerListener.bannedBlocks = bannedBlocksString.split("; ");

Related

How can I provide this sort of String builder class?

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());

Trouble calling a non-static method from an abstract class

I'm trying to call getSetting() from SettingsItem.java in SingleChoiceViewHolder.java. Is there a way to call getSetting() while keeping SettingsItem a non-static abstract class? Here's what I tried to add to SingleChoiceViewHolder.java, however Android Studio says that 'SettingsItem' is abstract; cannot be instantiated.:
SettingsItem instance = new SettingsItem();
instance.getSetting();
IntSetting setting = (IntSetting) getSetting();
mTextSettingDescription.setText(setting.getValue());
I also tried I tried converting SettingsItem to an interface and implementing it alongside SingleChoiceViewHolder extends SettingViewHolder but the original problem still remained.
The files are attached below.
SingleChoiceViewHolder.java:
public final class SingleChoiceViewHolder extends SettingViewHolder
{
private SingleChoiceSetting mItem;
private TextView mTextSettingName;
private TextView mTextSettingDescription;
public SingleChoiceViewHolder(View itemView, SettingsAdapter adapter)
{
super(itemView, adapter);
}
#Override
protected void findViews(View root)
{
mTextSettingName = (TextView) root.findViewById(R.id.text_setting_name);
mTextSettingDescription = (TextView) root.findViewById(R.id.text_setting_description);
}
#Override
public void bind(SettingsItem item)
{
mItem = (SingleChoiceSetting) item;
mTextSettingName.setText(item.getNameId());
if (item.getDescriptionId() == R.string.dynamic_descriptionId)
{
SettingsItem instance = new SettingsItem();
instance.getSetting();
IntSetting setting = (IntSetting) getSetting();
mTextSettingDescription.setText(setting.getValue());
}
if (item.getDescriptionId() > 0 && item.getDescriptionId() != R.string.dynamic_descriptionId)
{
mTextSettingDescription.setText(item.getDescriptionId());
}
}
#Override
public void onClick(View clicked)
{
getAdapter().onSingleChoiceClick(mItem);
}
SettingsItem.java:
public abstract class SettingsItem
{
public static final int TYPE_HEADER = 0;
public static final int TYPE_CHECKBOX = 1;
public static final int TYPE_SINGLE_CHOICE = 2;
public static final int TYPE_SLIDER = 3;
public static final int TYPE_SUBMENU = 4;
public static final int TYPE_INPUT_BINDING = 5;
public static final int TYPE_RADIO_BUTTON = 6;
private String mKey;
private String mSection;
private int mFile;
private Setting mSetting;
private int mNameId;
private int mDescriptionId;
public SettingsItem(String key, String section, int file, Setting setting, int nameId, int descriptionId)
{
mKey = key;
mSection = section;
mFile = file;
mSetting = setting;
mNameId = nameId;
mDescriptionId = descriptionId;
}
public String getKey()
{
return mKey;
}
public String getSection()
{
return mSection;
}
public int getFile()
{
return mFile;
}
public Setting getSetting()
{
return mSetting;
}
public void setSetting(Setting setting)
{
mSetting = setting;
}
public int getNameId()
{
return mNameId;
}
public int getDescriptionId()
{
return mDescriptionId;
}
public abstract int getType();
}
Since getSetting() is not a static method, you need to invoke it on an instance of some concrete class that extends the abstract class SettingsItem.
Think about it. If you have two instances of such a class, and the mSetting variable is different for the two instances, which one should be returned from a static-like call to getSetting()?
By definition abstract class means it is not instantiated but you can inherit from it. If you want to create many different objects with the same values but different names you can just extend SettingsItem.
Also, if you want more abstraction for future use you can create an interface with the same methods as the abstract methods in case you need to make customize methods for a different settings item.
Example:
interface SettingsInterface {
void doSomething();
}
class abstract SettingsItem implements SettingsInterface {
public void doSomething() {
System.out.println("Hello");
}
}
class RegularSettings extends SettingsItem {}
class CustomSettings implements SettingsInterface {
public void doSomething() {
System.out.println("Goodbye");
}
}
class TestClass {
public static void testAbstract(SettingsItem extendedAbstract) {
extendedAbstract.doSomething();
}
public static void testInterface(SettingsInterface interface) {
interface.doSomething();
}
public static void main(String[] args) {
SettingsItem abstractExtended = new RegularSettings();
// also could be CustomSettings instead of SettingsInterface
SettingsInterface customClass = new CustomSettings();
testInterface(abstractExtended);
testInterface(customClass);
testAbstract(abstractExtended);
// will throw errors since it doesn't extend SettingsItem
testAbstract(customClass);
}
}

Android - can't store a list in the Application class instance

I'm trying to store a list in the Application class instance as a global variable in one of my Android applications. Below is my Application class code:
public class DefectsApplication extends Application{
private NormalUser normalUser;
private ArrayList<Complaint> complaintList;
public String getTestString() {
return testString;
}
public void setTestString(String testString) {
this.testString = testString;
}
private String testString;
public NormalUser getNormalUser() {
return normalUser;
}
public void setNormalUser(NormalUser normalUser) {
this.normalUser = normalUser;
}
public ArrayList<Complaint> getComplaintList() {
return complaintList;
}
public void setComplaintList(ArrayList<Complaint> m_complaints) {
this.complaintList = complaintList;
}
}
Below is my code which is trying to access the fields from the Application class instance:
DefectsApplication defectsApplication = ((DefectsApplication)getApplicationContext());
defectsApplication.setComplaintList(m_complaints);
defectsApplication.setTestString("urghhhhhhhhh");
ArrayList<Complaint> complaintList = defectsApplication.getComplaintList();
String s = defectsApplication.getTestString();
In the above code, m_complaints is a list of objects. When I try to store a String, it works. But for a list, it doesn't. Please, help me to resolve this issue.
Probably, a typo is taking place:
public void setComplaintList(ArrayList<Complaint> m_complaints) {
this.complaintList = complaintList;
}
You're setting this.complaintList to itself which is initially null. Try
public void setComplaintList(ArrayList<Complaint> m_complaints) {
this.complaintList = m_complaints;
}

Checking passed params in unit testing with Mockito

I am trying to write really simple test with Mockito. I wrote small piece of code:
public class FlowTests {
#Mock
Calculator mockCalc = Mockito.mock(Calculator.class);
ConsoleView mockView = Mockito.mock(ConsoleView.class);
#Test
public void a01_Test() {
final String s = "2+2*2";
Controller c = new Controller();
c.setCalc(mockCalc);
Mockito.when(mockView.getFormule()).thenReturn(s); // I am not sure if it works
c.setView(mockView);
c.handle();
// TODO check if evaluate method has been invoked with "2+2*2"
}
}
Here you can see classes associated with this test:
public class Controller {
private IView view = new ConsoleView();
private ICalculator calc = new Calculator();
Double value = null;
public void handle() {
String formule = view.getFormule();
Double value = calc.evaluate(formule);
if (value != null) {
System.out.println("Result: ");
view.appendAnswer(value);
}
}
public void setCalc(ICalculator calc) {
this.calc = calc;
}
public void setView(IView view) {
this.view = view;
}
}
public class Calculator implements ICalculator {
public double evaluate(String s) {
...
char[] formuleChar = s.toCharArray();
result = calc.eval(formuleChar);
return result;
}
}
public class ConsoleView implements IView {
public String getFormule() {
... // getting s from console
return s;
}
public void appendAnswer(double r) {
System.out.println(r);
}
}
First goal of my test is to mock function getFormule() in ConsoleView to return always String s = "2+2*2". I did it but I am not sure if it works.
The main goal is to check if method evaluate() in Calculator class has been invoked with the same String. I have no idea how to that.
I cannot modify my code. I can only write a test.
Thank you in advance for your help!
Try something like this:
// check if evaluate method has been invoked with "2+2*2"
verify(mockCalc).evaluate("2+2*2");

Error trying to access class members (using Rhino)

Trying to create a Java/JS link using Rhino with two very simple objects, one having as one member an instance of the second class.
Running the code below gives the following error:
org.mozilla.javascript.EcmaError: TypeError: Cannot find default value
for object.
The problem seems to be accessing the member "a" from within second object. I've also tried with a getter like this:
public Object jsGet_a() {
return Context.toObject(a, this);
}
but i get the same error.
new A().doSmth(); is working fine, and outputs "I'm doing something"
new B().a.doSmth(); raises the error
Can anyone help me with a possible solution for this?
Thank you!
public class Test {
public static class A extends ScriptableObject implements Scriptable {
public A() {
};
public String getClassName() {
return "A";
}
public void jsFunction_doSmth() {
System.out.println("I'm doing something");
};
}
public static class B extends ScriptableObject implements Scriptable {
private A a = new A();
public B() {
};
public String getClassName() {
return "B";
}
public void jsConstructor() {
}
public A jsGet_a() {
return a;
}
}
public static void main(String[] args) {
try {
Context cx = Context.enter();
Scriptable scope = cx.initStandardObjects(null, true);
ScriptableObject.defineClass(scope, A.class);
ScriptableObject.defineClass(scope, B.class);
cx.compileString("" +
"new A().doSmth();" +
"new B().a.doSmth();" +
"", "", 1, null).exec(cx, scope);
} catch (Exception e) {
e.printStackTrace();
}
}
}
This seems to work:
Made the context and the global scope private static variables.
Added jsConstructor for the A class
In the jsConstructor for the B class, created a javascript object in code.
Used the Context.toObject(a, this); with return type of Scriptable in jsGet_a()
Finally, assigned the cx to the Context that was entered and scope to the global scope.
public class Test
{
private static Context cx;
private static ScriptableObject scope;
public static class A extends ScriptableObject implements Scriptable {
public A() {
}
public void jsConstructor() {
}
public String getClassName() {
return "A";
}
public void jsFunction_doSmth() {
System.out.println("I'm doing something");
}
}
public static class B extends ScriptableObject implements Scriptable {
private A a = new A();
public B() {
}
public String getClassName() {
return "B";
}
public void jsConstructor() {
Scriptable scriptable = cx.newObject(scope, "A");
this.put("a", this, scriptable);
}
public Scriptable jsGet_a() {
return Context.toObject(a, this);
}
}
public static void main(String[] args) {
try {
cx = Context.enter();
scope = cx.initStandardObjects(null, true);
ScriptableObject.defineClass(scope, A.class);
ScriptableObject.defineClass(scope, B.class);
cx.compileString("" +
"new A().doSmth();" +
"new B().a.doSmth();" +
"", "", 1, null).exec(cx, scope);
} catch (Exception e) {
e.printStackTrace();
}
}
}
new B().a.doSmth();
will not work as a is private.
new B().jsGet_a().jsFunction_doSmth();
seems like it should work.
According to the API docs, you could use the method
// Get a named property from the object.
get(java.lang.String name, Scriptable start)
in your java object. My guess is that you got the reflection conversion wrong in the above.

Categories