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 } }
Advertisement
Answer
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());