How to isolate an instance of a class with SuperCsv? - java

Actually I have a class ArticleModele where I store the content of the columns of the .csv, but I don't know how to access to a particular instance of the class which corresponds to a particular row in the .csv. Here is my code:
public static ArticleModele readWithCsvDozerBeanReader() throws Exception {
final CellProcessor[] processors = new CellProcessor[] {
new Optional(),
new Optional(),
new Optional()
};
ICsvDozerBeanReader beanReader = null;
try {
beanReader = new CsvDozerBeanReader(new FileReader(CSV_FILENAME), CsvPreference.EXCEL_NORTH_EUROPE_PREFERENCE);
beanReader.getHeader(true); // ignore the header
beanReader.configureBeanMapping(ArticleModele.class, FIELD_MAPPING);
ArticleModele articleModele;
while( (articleModele = beanReader.read(ArticleModele.class, processors)) != null ) {
System.out.println(String.format(" %s", articleModele));}
return articleModele;
}
finally {
if( beanReader != null ) {
beanReader.close();
}
}
}
}
And here is the class:
public class ArticleModele {
public String titre;
public String contenu;
public String attachement;
public ArticleModele(){}
public ArticleModele(String titre, String contenu, String attachement){
this.titre=titre;
this.contenu=contenu;
this.attachement=attachement;
}
public String getTitre(){
return titre;
}
public void setTitre(String titre){
this.titre=titre;
}
public String getContenu(){
return contenu;
}
public void setContenu(String contenu){
this.contenu=contenu;
}
public String getAttachement(){
return attachement;
}
public void setAttachement(String attachement){
this.attachement=attachement;
}
public String toString() {
return String.format("ArticleModele [titre=%s, content=%s, attachement=%s]", titre, contenu, attachement);
}
}

The code returns with last result, as it overwrites articleModele.
ArticleModele articleModele;
while( (articleModele = beanReader.read(ArticleModele.class, processors))
!= null) {
System.out.println(articleModele);
}
return articleModele;
So collect a list.
public static List<ArticleModele> readWithCsvDozerBeanReader() throws Exception {
List<ArticleModele> articleModele = new ArrayList<>();
ArticleModele articleModele;
while( (articleModele = beanReader.read(ArticleModele.class, processors))
!= null) {
System.out.println(articleModele);
articleModeles.add(articleModele);
}
return articleModeles;
If this works you can get the ith article. And walk the articles:
for (ArticleModele articleModele : articleModeles) { ...

For example if you want to fetch a row by title, you can have something like:
public static Map<String, ArticleModele> readWithCsvDozerBeanReader() throws Exception {
final CellProcessor[] processors = new CellProcessor[] {
new Optional(),
new Optional(),
new Optional()
};
Map<String, ArticleModele> map = new HashMap<String,ArticleModele>();
ICsvDozerBeanReader beanReader = null;
try {
beanReader = new CsvDozerBeanReader(new FileReader(CSV_FILENAME), CsvPreference.EXCEL_NORTH_EUROPE_PREFERENCE);
beanReader.getHeader(true); // ignore the header
beanReader.configureBeanMapping(ArticleModele.class, FIELD_MAPPING);
ArticleModele articleModele;
while( (articleModele = beanReader.read(ArticleModele.class, processors)) != null ) {
System.out.println(String.format(" %s", articleModele));}
map.put(articleModele .getTitre(),articleModele);
}
finally {
if( beanReader != null ) {
beanReader.close();
}
}
}
}
and get whatever articleModele you want using:
map.get("titre");

Related

Java, Refactoring case

I was given exercise that I need to refactor several java projects.
Only those 2 left which I truly don't have an idea how to refactor.
csv.writer
public class CsvWriter {
public CsvWriter() {
}
public void write(String[][] lines) {
for (int i = 0; i < lines.length; i++)
writeLine(lines[i]);
}
private void writeLine(String[] fields) {
if (fields.length == 0)
System.out.println();
else {
writeField(fields[0]);
for (int i = 1; i < fields.length; i++) {
System.out.print(",");
writeField(fields[i]);
}
System.out.println();
}
}
private void writeField(String field) {
if (field.indexOf(',') != -1 || field.indexOf('\"') != -1)
writeQuoted(field);
else
System.out.print(field);
}
private void writeQuoted(String field) {
System.out.print('\"');
for (int i = 0; i < field.length(); i++) {
char c = field.charAt(i);
if (c == '\"')
System.out.print("\"\"");
else
System.out.print(c);
}
System.out.print('\"');
}
}
csv.writertest
public class CsvWriterTest {
#Test
public void testWriter() {
CsvWriter writer = new CsvWriter();
String[][] lines = new String[][] {
new String[] {},
new String[] { "only one field" },
new String[] { "two", "fields" },
new String[] { "", "contents", "several words included" },
new String[] { ",", "embedded , commas, included",
"trailing comma," },
new String[] { "\"", "embedded \" quotes",
"multiple \"\"\" quotes\"\"" },
new String[] { "mixed commas, and \"quotes\"", "simple field" } };
// Expected:
// -- (empty line)
// only one field
// two,fields
// ,contents,several words included
// ",","embedded , commas, included","trailing comma,"
// """","embedded "" quotes","multiple """""" quotes"""""
// "mixed commas, and ""quotes""",simple field
writer.write(lines);
}
}
test
public class Configuration {
public int interval;
public int duration;
public int departure;
public void load(Properties props) throws ConfigurationException {
String valueString;
int value;
valueString = props.getProperty("interval");
if (valueString == null) {
throw new ConfigurationException("monitor interval");
}
value = Integer.parseInt(valueString);
if (value <= 0) {
throw new ConfigurationException("monitor interval > 0");
}
interval = value;
valueString = props.getProperty("duration");
if (valueString == null) {
throw new ConfigurationException("duration");
}
value = Integer.parseInt(valueString);
if (value <= 0) {
throw new ConfigurationException("duration > 0");
}
if ((value % interval) != 0) {
throw new ConfigurationException("duration % interval");
}
duration = value;
valueString = props.getProperty("departure");
if (valueString == null) {
throw new ConfigurationException("departure offset");
}
value = Integer.parseInt(valueString);
if (value <= 0) {
throw new ConfigurationException("departure > 0");
}
if ((value % interval) != 0) {
throw new ConfigurationException("departure % interval");
}
departure = value;
}
}
public class ConfigurationException extends Exception {
private static final long serialVersionUID = 1L;
public ConfigurationException() {
super();
}
public ConfigurationException(String arg0) {
super(arg0);
}
public ConfigurationException(String arg0, Throwable arg1) {
super(arg0, arg1);
}
public ConfigurationException(Throwable arg0) {
super(arg0);
}
}
configuration.test
public class ConfigurationTest{
#Test
public void testGoodInput() throws IOException {
String data = "interval = 10\nduration = 100\ndeparture = 200\n";
Properties input = loadInput(data);
Configuration props = new Configuration();
try {
props.load(input);
} catch (ConfigurationException e) {
assertTrue(false);
return;
}
assertEquals(props.interval, 10);
assertEquals(props.duration, 100);
assertEquals(props.departure, 200);
}
#Test
public void testNegativeValues() throws IOException {
processBadInput("interval = -10\nduration = 100\ndeparture = 200\n");
processBadInput("interval = 10\nduration = -100\ndeparture = 200\n");
processBadInput("interval = 10\nduration = 100\ndeparture = -200\n");
}
#Test
public void testInvalidDuration() throws IOException {
processBadInput("interval = 10\nduration = 99\ndeparture = 200\n");
}
#Test
public void testInvalidDeparture() throws IOException {
processBadInput("interval = 10\nduration = 100\ndeparture = 199\n");
}
#Test
private void processBadInput(String data) throws IOException {
Properties input = loadInput(data);
boolean failed = false;
Configuration props = new Configuration();
try {
props.load(input);
} catch (ConfigurationException e) {
failed = true;
}
assertTrue(failed);
}
#Test
private Properties loadInput(String data) throws IOException {
InputStream is = new StringBufferInputStream(data);
Properties input = new Properties();
input.load(is);
is.close();
return input;
}
}
Ok, here some advice regarding the code.
CsvWriter
The bad thing is that you print everything to System.out. It will be hard to test without mocks. Instead I suggest you to add field PrintStream which defines where all data will go.
import java.io.PrintStream;
public class CsvWriter {
private final PrintStream printStream;
public CsvWriter() {
this.printStream = System.out;
}
public CsvWriter(PrintStream printStream) {
this.printStream = printStream;
}
...
You then write everything to this stream. This refactoring easy since you use replace function(Ctrl+R in IDEA). Here is the example how you do it.
private void writeField(String field) {
if (field.indexOf(',') != -1 || field.indexOf('\"') != -1)
writeQuoted(field);
else
printStream.print(field);
}
Others stuff seems ok in this class.
CsvWriterTest
First thing first you don't check all logic in a single method. Make small methods with different kind of tests. It's ok to keep your current test though. Sometimes it's useful to check most of the logic in a complex scenario.
Also pay attention to the names of the methods. Check this
Obviously you test doesn't check the results. That's why we need this functionality with PrintStream. We can build a PrintStream on top of the instance of ByteArrayOutputStream. We then construct a string and check if the content is valid. Here is how you can easily check what was written
public class CsvWriterTest {
private ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
private PrintStream printStream = new PrintStream(byteArrayOutputStream);
#Test
public void testWriter() {
CsvWriter writer = new CsvWriter(printStream);
... old logic here ...
writer.write(lines);
String result = new String(byteArrayOutputStream.toByteArray());
Assert.assertTrue(result.contains("two,fields"));
Configuration
Make fields private
Make messages more concise
ConfigurationException
Seems good about serialVersionUID. This thing is needed for serialization/deserialization.
ConfigurationTest
Do not use assertTrue(false/failed); Use Assert.fail(String) with some message which is understandable.
Tip: if you don't have much experience and need to refactor code like this, you may want to read some chapters of Effective Java 2nd edition by Joshua Bloch. The book is not so big so you can read it in a week and it has some rules how to write clean and understandable code.

JavaFX TreeView JSON Ex/Import via GSON

I´m looking for a way to export a JavaFX TreeView to JSON. To make this whole process simple, I use GSON. Its exporting the value of a treeItem well, but when I try to use the whole Tree its ending in a stack overflow. I believe this has something to do with the parent/child attribute. Is there a way to prevent GSON from exporting this attribute.
And how do I import the whole thing again? I wasn't able to import a simple object of mine, because GSON can't handle Properties.
You need to use a custom type adapter. Furthermore you can prevent stackoverflows by using loops instead of recursion:
public class TreeItemTypeAdapter<T> extends TypeAdapter<TreeItem<T>> {
private Gson gson;
public void setGson(Gson gson) {
this.gson = gson;
}
private final Class<T> valueClass;
public TreeItemTypeAdapter(Class<T> valueClass) {
if (valueClass == null) {
throw new IllegalArgumentException();
}
this.valueClass = valueClass;
}
public static TreeItemTypeAdapter<String> createStringTreeItemAdapter() {
return new TreeItemTypeAdapter<>(String.class);
}
private void writeValue(JsonWriter writer, T t) throws IOException {
if (gson == null) {
writer.value(Objects.toString(t, null));
} else {
gson.toJson(t, valueClass, writer);
}
}
private T readValue(JsonReader reader) throws IOException {
if (gson == null) {
Object value = reader.nextString();
return (T) value;
} else {
return gson.fromJson(reader, valueClass);
}
}
#Override
public void write(JsonWriter writer, TreeItem<T> t) throws IOException {
writer.beginObject().name("value");
writeValue(writer, t.getValue());
writer.name("children").beginArray();
LinkedList<Iterator<TreeItem<T>>> iterators = new LinkedList<>();
iterators.add(t.getChildren().iterator());
while (!iterators.isEmpty()) {
Iterator<TreeItem<T>> last = iterators.peekLast();
if (last.hasNext()) {
TreeItem<T> ti = last.next();
writer.beginObject().name("value");
writeValue(writer, ti.getValue());
writer.name("children").beginArray();
iterators.add(ti.getChildren().iterator());
} else {
writer.endArray().endObject();
iterators.pollLast();
}
}
}
#Override
public TreeItem<T> read(JsonReader reader) throws IOException {
if (gson == null && !valueClass.getName().equals("java.lang.String")) {
throw new IllegalStateException("cannot parse classes other than String without gson provided");
}
reader.beginObject();
if (!"value".equals(reader.nextName())) {
throw new IOException("value expected");
}
TreeItem<T> root = new TreeItem<>(readValue(reader));
TreeItem<T> item = root;
if (!"children".equals(reader.nextName())) {
throw new IOException("children expected");
}
reader.beginArray();
int depth = 1;
while (depth > 0) {
if (reader.hasNext()) {
reader.beginObject();
if (!"value".equals(reader.nextName())) {
throw new IOException("value expected");
}
TreeItem<T> newItem = new TreeItem<>(readValue(reader));
item.getChildren().add(newItem);
item = newItem;
if (!"children".equals(reader.nextName())) {
throw new IOException("children expected");
}
reader.beginArray();
depth++;
} else {
depth--;
reader.endArray();
reader.endObject();
item = item.getParent();
}
}
return root;
}
}
public static void main(String[] args) {
TreeItem<String> ti = new TreeItem<>("Hello world");
TreeItem<String> ti2 = new TreeItem<>("42");
TreeItem<String> ti3 = new TreeItem<>("Foo");
TreeItem<String> ti4 = new TreeItem<>("Bar");
ti.getChildren().addAll(ti2, ti3);
ti2.getChildren().add(ti4);
TreeItemTypeAdapter<String> adapter = new TreeItemTypeAdapter<>(String.class);
Gson gson = new GsonBuilder().registerTypeAdapter(TreeItem.class, adapter).create();
adapter.setGson(gson);
System.out.println(gson.toJson(ti));
System.out.println(toString(gson.fromJson("{\"value\":\"Hello world\",\"children\":[{\"value\":\"42\",\"children\":[{\"value\":\"Bar\",\"children\":[]}]},{\"value\":\"Foo\",\"children\":[]}]}",
TreeItem.class)));
}
private static String toString(TreeItem ti) {
StringBuilder sb = new StringBuilder("TreeItem [ value: \"").append(ti.getValue()).append("\" children [");
boolean notFirst = false;
for (TreeItem i : (List<TreeItem>) ti.getChildren()) {
if (notFirst) {
sb.append(",");
} else {
notFirst = true;
}
sb.append(toString(i));
}
return sb.append("]]").toString();
}

Java SAX parser : read element of Parent Element when Child element also contains same element

<MyWorld>
<MyWorldId>SGSNPackage2</MyWorldId>
<MyNation>
<state>GROWING</state>
</MyNation>
<state>HAPPY</state>
</MyWorld>
My Parser class :
import java.io.IOException;
import java.io.StringReader;
import java.util.*;
import javax.xml.parsers.*;
import org.xml.sax.*;
import org.xml.sax.helpers.DefaultHandler;
public class MyParser extends DefaultHandler {
private static final String EMPTY_VALUE = "";
private final StringBuilder characters = new StringBuilder();
private boolean read;
private boolean elementFound;
private boolean elementPropertyFound;
private boolean elementIdFound;
private boolean elementWithIdFound;
private boolean elementProperty;
private boolean elementPropertyIsList;
private List<String> properties;
private final Set<String> propertyAlreadyExist = new HashSet<String>();
private String elementType;
private List<String> primaryKeyAttributes;
private String elementIdValue;
private String elementIdName;
private Map<String, Object> elementPropertiesMap;
Map<String, Object> complexMapAttribute = new HashMap<>();
public void setAttributes(final List<String> attributes) {
this.properties = attributes;
}
public void setFdnType(final String fdnType) {
this.elementType = fdnType;
}
public void setPrimaryKeyAttributes(final List<String> primaryKeyAttributes) {
this.primaryKeyAttributes = primaryKeyAttributes;
}
public void setKeyValue(final String keyValue) {
this.elementIdValue = keyValue;
}
#Override
public void startElement(final String uri, final String localName, final String qName, final Attributes attribute) throws SAXException {
if (qName.equalsIgnoreCase(elementType)) {
if (!elementWithIdFound) {
elementFound = true;
} else {
elementWithIdFound = false;
}
} else if (primaryKeyAttributes.contains(qName) && elementFound) {
elementIdFound = true;
read = true;
} else if (properties.contains(qName) && elementWithIdFound) {
if (propertyAlreadyExist.contains(qName)) {
elementPropertyIsList = true;
}
propertyAlreadyExist.add(qName);
elementIdName = qName;
elementPropertyFound = true;
read();
read = true;
elementProperty = false;
} else if(elementFound && elementWithIdFound && elementPropertyFound){
elementProperty = true;
read();
read = true;
}
}
#SuppressWarnings("unchecked")
#Override
public void endElement(final String uri, final String localName, final String qName) throws SAXException {
final String text;
if (primaryKeyAttributes.contains(qName) || properties.contains(qName)) {
if (elementFound && elementWithIdFound && elementPropertyFound) {
text = readBuffer();
if (elementIdName != null) {
if(elementPropertyIsList) {
if(elementProperty){
if(null != elementPropertiesMap.get(elementIdName) && elementPropertiesMap.get(elementIdName)!= EMPTY_VALUE){
final List<Map<String,Object>> listOfComplexAttribute = new ArrayList<>();
if(elementPropertiesMap.get(elementIdName) instanceof List){
listOfComplexAttribute.addAll((List<Map<String, Object>>) elementPropertiesMap.get(elementIdName));
}else{
listOfComplexAttribute.add((Map<String, Object>) elementPropertiesMap.get(elementIdName));
}
listOfComplexAttribute.add(new HashMap<String, Object>(complexMapAttribute));
elementPropertiesMap.put(elementIdName, new ArrayList<Map<String, Object>>(listOfComplexAttribute));
}else{
elementPropertiesMap.put(elementIdName, new HashMap<String, Object>(complexMapAttribute));
}
complexMapAttribute.clear();
}else{
final List<Object> attributeValueList = new ArrayList<>();
if(null != elementPropertiesMap.get(elementIdName) && elementPropertiesMap.get(elementIdName)!= EMPTY_VALUE){
if(elementPropertiesMap.get(elementIdName) instanceof List){
attributeValueList.addAll((List<Object>) elementPropertiesMap.get(elementIdName));
}else{
attributeValueList.add(elementPropertiesMap.get(elementIdName));
}
attributeValueList.add(text);
elementPropertiesMap.put(elementIdName, new ArrayList<Object>(attributeValueList));
}else{
elementPropertiesMap.put(elementIdName,text);
}
}
} else {
if (elementProperty) {
elementPropertiesMap.put(elementIdName,new HashMap<String, Object>(complexMapAttribute));
complexMapAttribute.clear();
} else {
elementPropertiesMap.put(elementIdName,text);
}
}
elementIdName = null;
elementPropertyFound =false;
}
} else {
if (elementIdFound) {
if (readBuffer().equalsIgnoreCase(elementIdValue)) {
elementWithIdFound = true;
} else {
elementIdFound = false;
elementWithIdFound = false;
elementFound = false;
elementIdName = null;
}
}
}
}else if (elementFound && elementWithIdFound && elementPropertyFound && elementProperty){
text = readBuffer();
complexMapAttribute.put(qName, text);
}
}
#Override
public void characters(final char[] ch, final int start, final int length) throws SAXException {
if (read) {
characters.append(new String(ch, start, length));
}
}
public void parseData(final String data) {
elementPropertiesMap = new HashMap<>();
for (String attributeName : properties) {
elementPropertiesMap.put(attributeName, EMPTY_VALUE);
}
final SAXParserFactory parserFactor = SAXParserFactory.newInstance();
try {
final SAXParser parser = parserFactor.newSAXParser();
parser.parse(new InputSource(new StringReader(data)), this);
} catch (ParserConfigurationException | SAXException | IOException e) {
throw new RuntimeException((String) e.getMessage());
}
}
private void read() {
read = true;
characters.setLength(0);
}
private String readBuffer() {
final String chars = characters.toString();
characters.setLength(0);
read = false;
return chars;
}
}
I have above XML and I want to read the state of MyWorld. My SAX parser returns me the value of state as {GROWING. HAPPY} as attribures/element can occurs more than one so I handled accordingly.
What I want, I should get only "HAPPY" when I try to find state while parsing it ?
How I can achieve it ?
Thnaks a million for yur help!!

Enumeration<URL> configs.hasMoreElements() gives false

I am developing a voice-based app in android and facing some problems please see below code,
Java File 1
file = .wav file
public static AudioInputStream getAudioInputStream(File file) throws UnsupportedAudioFileException, IOException {
return getAudioInputStreamImpl(file);
}
private static AudioInputStream getAudioInputStreamImpl(Object source) throws UnsupportedAudioFileException, IOException {
GetAudioInputStreamAudioFileReaderAction action = new GetAudioInputStreamAudioFileReaderAction(source);
doAudioFileReaderIteration(action);
AudioInputStream audioInputStream = action.getAudioInputStream();
if (audioInputStream != null) {
return audioInputStream;
}
throw new UnsupportedAudioFileException("format not supported");
}
private static void doAudioFileReaderIteration(AudioFileReaderAction action) throws IOException {
Iterator audioFileReaders = TAudioConfig.getAudioFileReaders();
boolean bCompleted = false;
while (audioFileReaders.hasNext() && !bCompleted) {
AudioFileReader audioFileReader = (AudioFileReader) audioFileReaders.next();
bCompleted = action.handleAudioFileReader(audioFileReader);
}
}
Java file 2 (TAudioConfig)
public static synchronized Iterator<AudioFileReader> getAudioFileReaders() {
Iterator<AudioFileReader> it;
synchronized (TAudioConfig.class) {
it = getAudioFileReadersImpl().iterator();
}
return it;
}
private static synchronized Set<AudioFileReader> getAudioFileReadersImpl() {
Set<AudioFileReader> set;
synchronized (TAudioConfig.class) {
if (sm_audioFileReaders == null) {
sm_audioFileReaders = new ArraySet();
registerAudioFileReaders();
}
set = sm_audioFileReaders;
}
return set;
}
private static void registerAudioFileReaders() {
TInit.registerClasses(AudioFileReader.class, new C00001());
}
Java File 3 (TInit)
public static void registerClasses(Class providerClass, ProviderRegistrationAction action) {
Iterator providers = Service.providers(providerClass);
if (providers != null) {
while (providers.hasNext()) {
try {
action.register(providers.next());
} catch (Throwable e) {
}
}
}
}
Java File 4 (Service)
public static Iterator<?> providers(Class<?> cls) {
String strFullName = "com/example/voiceautomator/AudioFileReader.class";
Iterator<?> iterator = createInstancesList(strFullName).iterator();
return iterator;
}
private static List<Object> createInstancesList(String strFullName) {
List<Object> providers = new ArrayList<Object>();
Iterator<?> classNames = createClassNames(strFullName);
if (classNames != null) {
while (classNames.hasNext()) {
String strClassName = (String) classNames.next();
try {
Class<?> cls = Class.forName(strClassName, REVERSE_ORDER, ClassLoader.getSystemClassLoader());
providers.add(0, cls.newInstance());
} catch (Throwable e) {
}
}
}
return providers;
}
private static Iterator<String> createClassNames(String strFullName) {
Set<String> providers = new ArraySet<String>();
Enumeration<?> configs = null;
try {
configs = Service.class.getClassLoader().getSystemResources(strFullName);
} catch (Throwable e) {
}
if (configs != null) {
while (configs.hasMoreElements()) {
URL configFileUrl = (URL) configs.nextElement();
InputStream input = null;
try {
input = configFileUrl.openStream();
} catch (Throwable e2) {
}
if (input != null) {
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
try {
for (String strLine = reader.readLine(); strLine != null; strLine = reader.readLine()) {
strLine = strLine.trim();
int nPos = strLine.indexOf(35);
if (nPos >= 0) {
strLine = strLine.substring(0, nPos);
}
if (strLine.length() > 0) {
providers.add(strLine);
}
}
} catch (Throwable e22) {
}
}
}
}
Iterator<String> iterator = providers.iterator();
return iterator;
}
getClassLoader().getSystemResources in the Java File 4 (Service) gives me TwoEnumerationsInOne and configs.hasMoreElements() gives false so not able to go into while loop.
AudioFileReader.java is included in the package
Please guide me to resolve this issue?
Please don't forget I am working on this code in an android project
Please see the value of configs here
http://capsicumtech.in/Screenshot_1.png
Thanks in advance.

JSON to JSON conversion in Java

I am trying to acheive JSON to JSON conversion in java based on the specification given on runtime.
Example : if at runtime source : com.gsdetails.gname,target : com.track.trackName (i.e source field should be mapped to target field in generated JSON)
My approach was to create N-array tree for the specification part and do breadth first travesal (get queue with it to craeate structure for resulting json)
I am using Jackson api to create tree from input JSON and traversing both queue(bfs) and input tree to create resulting json.
Unable to get expected output
PS : I thought of using JOLT api but it will not serve my purpose
Tree (for specification)
public class TrieBuilder {
public static void main(String[] args) throws Exception {
createSpec();
}
public static Trie createSpec() throws Exception {
BufferedReader reader = new BufferedReader(
new FileReader(""));
String currentLine = reader.readLine();
Trie trie = new Trie();
while (currentLine != null) {
String[] lines = currentLine.split(",");
String sourceLine = lines[0];
String targetLine = lines[1];
String sourcePath = sourceLine.split("=")[1];
String targetPath = targetLine.split("=")[1];
trie.insertWord(sourcePath.trim(), targetPath.trim());
currentLine = reader.readLine();
}
return trie;
}
}
class TrieNode {
String source;// consider this as content/reference point of a tree
String target;
boolean isEnd;
int count;
List childList;
boolean isRoot;
/* Constructor */
public TrieNode(String source, String target) {
childList = new ArrayList<TrieNode>();
isEnd = false;
count = 0;
this.source = source;
this.target = target;
}
public TrieNode subNodeWord(String word) {
if (childList != null) {
for (TrieNode eachChild : childList)
if (eachChild.source.equals(word))
return eachChild;
}
return null;
}
}
class Trie {
public TrieNode root;
/* Constructor */
public Trie() {
root = new TrieNode("", "");
}
public void insertWord(String sourceWords, String targetWords) {
if (searchWord(sourceWords) == true)
return;
TrieNode current = root;
String[] sourceArray = sourceWords.split(":");
String[] targetArray = targetWords.split(":");
for (int i = 0; i < sourceArray.length; i++) {
TrieNode child = current.subNodeWord(sourceArray[i]);
if (child != null) {
current = child;
} else {
current.childList.add(new TrieNode(sourceArray[i],
targetArray[i]));
current = current.subNodeWord(sourceArray[i]);
}
current.count++;
}
current.isEnd = true;
}
public boolean searchWord(String words) {
TrieNode current = root;
for (String word : words.split(":")) {
if (current.subNodeWord(word) == null) {
return false;
} else {
current = current.subNodeWord(word);
}
}
if (current.isEnd == true)
return true;
return false;
}
public Queue<TrieNode> bfsTraversal(TrieNode node) {
// TODO need to add logic for bfs/dfs for traversing the trie
Queue<TrieNode> queue = new LinkedList<>();
Queue<TrieNode> tempQueue = new LinkedList<>();
queue.add(root);
while (!queue.isEmpty()) {
TrieNode tempNode = queue.poll();
tempQueue.add(tempNode);
int counter = tempNode.childList.size(), i = 0;
if (tempNode == null)
break;
if (!tempNode.source.isEmpty())
System.out.println("Source :" + tempNode.source
+ " Target : " + tempNode.target);
while (i < counter) {
queue.add(tempNode.childList.get(i++));
}
}
tempQueue.poll();
return tempQueue;
}
Source to target mapping file :
source = com:track:trackDetails:fname, target = gsUser:gsProp:gsDetails:gsFirstName
source = com:track:trackDetails:lname, target = gsUser:gsProp:gsDetails:gsLastName
helper class (Actual transform):
public class JsonHelperClass{
// private Files file = null;// create a tempfile
private JsonNodeFactory factory;
private JsonFactory jsonFactory;
private ObjectMapper mapper;
private JsonNode jsonRoot;
private Queue<TrieNode> queue;
// private JsonParser jsonParser =
public JsonHelperClass() throws JsonProcessingException, IOException {
this.factory = JsonNodeFactory.instance;
this.jsonFactory = new JsonFactory();
this.mapper = new ObjectMapper();
this.jsonRoot = mapper.readTree(new File("json with data"));
}
public static void main(String[] args) throws Exception, Exception {
JsonHelperClass helperClass = new JsonHelperClass();
helperClass.jsonCreator();
ObjectNode objectNode = null;
ObjectNode result = helperClass.createJsonRecursively(objectNode);
System.out.println(result.toString());
}
public void jsonCreator() throws Exception {
Trie trie = TrieBuilder.createSpec();
queue = trie.bfsTraversal(trie.root);
}
public ObjectNode createJsonRecursively(ObjectNode outputJson) throws Exception {
TrieNode nodeOfQueue = queue.poll();
if(outputJson == null){
// create a root of the JSON
outputJson = factory.objectNode();
outputJson.put(nodeOfQueue.target, createJsonRecursively(outputJson));
}else if (jsonRoot.get(nodeOfQueue.source).isObject()){
// create an object to conatin other values/object
ObjectNode objectNode = factory.objectNode();
objectNode.put(nodeOfQueue.target,createJsonRecursively(outputJson));
outputJson.putAll(objectNode);
}else if(jsonRoot.get(nodeOfQueue.source).isArray()){
// create an array node and call for to create value it contains
ArrayNode arrayNode = factory.arrayNode();
int size = jsonRoot.get(nodeOfQueue.source).size();
for(int index = 0 ; index < size ; index++){
arrayNode.add(jsonRoot.get(nodeOfQueue.source).get(index));
}
outputJson.put(nodeOfQueue.target,arrayNode);
}else if(nodeOfQueue.isEnd){
// create leaf node
outputJson.put(nodeOfQueue.target, jsonRoot.get(nodeOfQueue.source));
return outputJson;
}
return outputJson;
}

Categories