/******************************************************************************* * Copyright (C) 2013 JMaNGOS <http://jmangos.org/> * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see <http://www.gnu.org/licenses/>. ******************************************************************************/ package org.jmangos.tools.dbc.dataholder; import java.io.BufferedWriter; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.Writer; import java.lang.reflect.Array; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import javax.xml.bind.annotation.XmlAttribute; public abstract class DBCStruct<T extends DBCStruct<T>> extends DBCBaseStruct implements Iterable<T>, Iterator<T>, Cloneable { private int count; private int skiplenght = 0; private int currposition = 0; private Object[] FiledsName; private boolean mode; @SuppressWarnings("unchecked") @Override protected <M extends Member> M[] array(final M[] param) { if (param.length > 0) { if (INTERNALSTRING.isInstance(param)) { for (int i = 0; i < param.length;) { param[i++] = (M) new InternalString(); } return param; } else { return super.array(param); } } else { return null; } } @SuppressWarnings("unchecked") public T LookupEntry(final int i) { setCurrposition(i); setByteBufferPosition(HEADER_SIZE + ((size() + this.skiplenght) * i)); return (T) this; } public final void setStringBufferPosition(final int stringBufPos) { this.stringBufPos = stringBufPos; } @SuppressWarnings("unchecked") @Override public T clone() { T re = null; try { re = (T) this.getClass().newInstance(); } catch (final InstantiationException e) { e.printStackTrace(); } catch (final IllegalAccessException e1) { e1.printStackTrace(); } re.setByteBuffer(getByteBuffer(), getByteBufferPosition()); re.setStringBufferPosition(this.stringBufPos); return re; } public int getCount() { return this.count; } public void setCount(final int count) { this.count = count; } public int getSkiplenght() { return this.skiplenght; } public void setSkipLenght(final int skiplenght) { this.skiplenght = skiplenght; } @Override public boolean hasNext() { return (getCurrposition() + 1) < getCount(); } @Override public T next() { if (hasNext()) { System.out.print("\r"); System.out.print("[ " + (getCurrposition() + 1) + " ] of [ " + this.count + " ] "); return LookupEntry(getCurrposition() + 1); } return null; } @Override public void remove() { } public void saveToXML(final String path, final boolean full) throws IOException { this.mode = full; final Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(path + this.getClass().getSimpleName() + ".xml"), "UTF-8")); try { final String header = this.getClass().getSimpleName() + "List"; cacheFields(full); out.write("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n"); out.write("<" + header + ">\n"); toXML(out); out.write("</" + header + ">"); out.flush(); } catch (final FileNotFoundException e) { e.printStackTrace(); } finally { out.close(); } } public void cacheFields(final boolean mode) { final Field[] f = this.getClass().getFields(); final List<String> TFiledsName = new ArrayList<String>(); for (int i = 0; i < f.length; i++) { if (Modifier.isStatic(f[i].getModifiers()) || !f[i].isAnnotationPresent(XmlAttribute.class)) { continue; } final XmlAttribute property = f[i].getAnnotation(XmlAttribute.class); if ((property.name() != null) & (property.required() | mode)) { try { if (f[i].getType().isArray()) { final Object sd = f[i].get(this); for (int j = 0; j < Array.getLength(sd); j++) { TFiledsName.add(property.name() + (j + 1)); } } else if ((f[i].getType() == InternalString.class) || (f[i].getType() == MultiInternalString.class)) { if (mode) { TFiledsName.add(property.name()); } } else { TFiledsName.add(property.name()); } } catch (final IllegalArgumentException e) { e.printStackTrace(); } catch (final IllegalAccessException e) { e.printStackTrace(); } } }; this.FiledsName = TFiledsName.toArray(); } public void toXML(final Writer out) throws IOException { final Field[] f = this.getClass().getFields(); int counter = 0; do { out.write("\t<" + this.getClass().getSimpleName() + " "); for (int i = 0; i < f.length; i++) { if (Modifier.isStatic(f[i].getModifiers()) || !f[i].isAnnotationPresent(XmlAttribute.class)) { continue; } final XmlAttribute property = f[i].getAnnotation(XmlAttribute.class); if ((property.name() != null) & (property.required() | this.mode)) { try { if ((f[i].getType() == InternalString.class) || (f[i].getType() == MultiInternalString.class)) { if (this.mode) { final String escapedString = escapeCharacters((f[i].get(this)).toString()); if ((escapedString.length() > 0) | property.required()) { writeAttr((String) this.FiledsName[counter], escapedString, out); } counter++; } } else if (f[i].getType().isArray()) { final Object sd = f[i].get(this); for (int j = 0; j < Array.getLength(sd); j++) { Array.get(sd, j); writeAttr((String) this.FiledsName[counter++], Array.get(sd, j).toString(), out); } } else { writeAttr((String) this.FiledsName[counter++], f[i].get(this).toString(), out); } } catch (final IllegalArgumentException e) { e.printStackTrace(); } catch (final IllegalAccessException e) { e.printStackTrace(); } } } out.write("/>\n"); counter = 0; } while (this.next() != null); } public void writeAttr(final String name, final String value, final Writer out) throws IOException { out.write(name + "=\"" + value + "\" "); } public String escapeCharacters(final String str) { if (str == null) { return ""; } StringBuffer s = new StringBuffer(str); for (int i = 0; i < s.length(); i++) { switch (s.charAt(i)) { case '\"': s = s.replace(i++, i, """); break; case '&': s = s.replace(i++, i, "&"); break; case '<': s = s.replace(i++, i, "<"); break; case '>': s = s.replace(i++, i, ">"); break; case '\'': s = s.replace(i++, i, "'"); break; default: break; } } return s.toString(); } public int getCurrposition() { return this.currposition; } public void setCurrposition(final int currposition) { this.currposition = currposition; } @SuppressWarnings("unchecked") @Override public T iterator() { return (T) this; } }