package com.xmlit.project.engine.marshal;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java1.util.regex.Matcher;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java1.util.regex.*;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import com.xmlit.project.engine.struct.Struct;
import com.xmlit.project.engine.struct.StructChoice;
import com.xmlit.project.engine.struct.StructSequence;
import com.xmlit.project.engine.struct.StructSimple;
import com.xmlit.project.engine.struct.impl.CalcContext;
public class UnmarshalImpl implements Unmarshal {
static DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
static DocumentBuilder db = null;// dbf.newDocumentBuilder();
static {
try {
db = dbf.newDocumentBuilder();
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public Document unmarshal(String message, Struct struct) {
Document doc = db.newDocument();
String regex = struct.calcRegex();
// System.out.println(regex);
Element element = doUnmarshal(null, message, struct, doc, regex,
new UnmarshalContext(0));
doc.appendChild(element);
return doc;
}
public Element doUnmarshal(Element element, String message, Struct struct,
Document doc, String regex, UnmarshalContext context) {
if (StructPatternHelper.patternMapping.get(struct) == null) {
StructPatternHelper.patternMapping.put(struct,
Pattern.compile(regex));
}
Pattern patt = StructPatternHelper.patternMapping.get(struct);
Matcher matches = patt.matcher(message);
matches.lookingAt();
int lastPossition = getLast(matches);
/*List<String> matchesl = new ArrayList<String>();
if (matches.matches()) {
for (int i = 0; i <= matches.groupCount(); i++) {
matchesl.add(matches.group(i));
// System.out.println(m1.group(i));
}
}
*/
try {
return createElement(element, struct, doc, matches, context);
} catch (Exception e) {
throw new RuntimeException("Last possition is:" + lastPossition,
e);
}
}
private int getLast(Matcher matches) {
try {
Field f = Matcher.class.getDeclaredField("last");
f.setAccessible(true);
return f.getInt(matches);
} catch (Exception e) {
return 0;
}
//return 0;
}
private Element createElement(Element element, Struct struct, Document doc,
Matcher matches, UnmarshalContext context) {
if (struct.getMaxOccurrences() != 1
&& matches.group(struct.getRegularExpressionIndex()
- context.baseIndex) != null
&& struct.getRegularExpressionIndexWithoutOccur() >= context.baseIndex
&& !matches.group(
struct.getRegularExpressionIndexWithoutOccur()
- context.baseIndex).equals(
matches.group(struct.getRegularExpressionIndex()
- context.baseIndex))) {
String field = matches.group(struct
.getRegularExpressionIndexWithoutOccur()
- context.baseIndex);
if (StructPatternHelper.patternPureMapping.get(struct) == null) {
StructPatternHelper.patternPureMapping.put(struct,
Pattern.compile(struct.getRegularExpressionPure()));
}
Pattern datePatt = StructPatternHelper.patternPureMapping
.get(struct);
Matcher m = datePatt.matcher(field);
while (m.find()) {
// struct.setRegularExpression(struct.getRegularExpressionPure());
String group = m.group();
if (group == null || "".equals(group))
continue;
Element childElement = doUnmarshal(element, group, struct, doc,
struct.getRegularExpressionPure(),
new UnmarshalContext(
struct.getRegularExpressionIndex() - 1));
if (childElement != null)
element.appendChild(childElement);
}
return element;
} else {
if (struct instanceof StructSequence) {
return createElementSequence(element, (StructSequence) struct,
doc, matches, context);
} else if (struct instanceof StructChoice) {
return createElementChoice(element, (StructChoice) struct, doc,
matches, context);
} else {
return createElementSimple(element, (StructSimple) struct, doc,
matches, context);
}
}
}
private Element createElementSimple(Element parent, StructSimple struct,
Document doc, Matcher matches, UnmarshalContext context) {
String val = matches.group(struct.getRegularExpressionIndex()
- context.baseIndex);
if (val != null) {
Element result = doc.createElement(struct.getName());
result.setTextContent(val);
parent.appendChild(result);
return result;
}
return null;
}
private Element createElementChoice(Element parent, Struct struct,
Document doc, Matcher matches, UnmarshalContext context) {
String val = matches.group(struct.getRegularExpressionIndex()
- context.baseIndex);
if (val != null && !"".equals(val)) {
Element result = doc.createElement(struct.getName());
for (Struct child : struct.getChildren()) {
createElement(result, child, doc, matches, context);
}
if (parent != null)
parent.appendChild(result);
return result;
}
return null;
}
private Element createElementSequence(Element element, Struct struct,
Document doc, Matcher matches, UnmarshalContext context) {
return createElementChoice(element, struct, doc, matches, context);
}
}