[New] added testing of the *byId() methods

Here i found a conceptual problem where the *byId() methods didn't
properly resolve ObjectRefs and add them to the TX because, we added the
ObjectRefs to the filter, which made the TX resolve PersistenContexts by
the wrong type.

Now we always add the same type of object to the ObjectFilter; the
PersistentContext. This means that when we call ObjectDao.add(T), etc.
we must already create such the context. This helps resolve another
issue at the back of my mind: We don't want to partially commit a TX if
such a basic information as the object's CTX is not available.
This commit is contained in:
Robert von Burg 2013-10-19 17:43:36 +02:00
parent a0d5904db9
commit bce78769c0
16 changed files with 160 additions and 381 deletions

View File

@ -145,6 +145,7 @@ public class FileDao {
if (this.verbose) {
String msg = "Path for operation {0} for {1} is at {2}"; //$NON-NLS-1$
msg = MessageFormat.format(msg, operation, objectRef.getName(), path.getAbsolutePath());
logger.info(msg);
}
}

View File

@ -43,59 +43,80 @@ public class ObjectDao {
private final ObjectFilter objectFilter;
private final FileDao fileDao;
private final PersistenceTransaction tx;
private PersistenceContextFactoryDelegator ctxFactoryDelegator;
public ObjectDao(PersistenceTransaction tx, FileDao fileDao, ObjectFilter objectFilter) {
this.tx = tx;
this.fileDao = fileDao;
this.objectFilter = objectFilter;
this.ctxFactoryDelegator = this.tx.getRealm().getCtxFactoryDelegator();
}
public <T> void add(T object) {
assertNotClosed();
assertNotNull(object);
this.objectFilter.add(object);
PersistenceContext<T> ctx = createCtx(object);
ctx.setObject(object);
this.objectFilter.add(object.getClass().getName(), ctx);
}
@SuppressWarnings("unchecked")
public <T> void addAll(List<T> objects) {
assertNotClosed();
assertNotNull(objects);
if (!objects.isEmpty())
this.objectFilter.addAll((List<Object>) objects);
if (!objects.isEmpty()) {
for (T object : objects) {
PersistenceContext<T> ctx = createCtx(object);
ctx.setObject(object);
this.objectFilter.add(object.getClass().getName(), ctx);
}
}
}
public <T> void update(T object) {
assertNotClosed();
assertNotNull(object);
this.objectFilter.update(object);
PersistenceContext<T> ctx = createCtx(object);
ctx.setObject(object);
this.objectFilter.update(object.getClass().getName(), ctx);
}
@SuppressWarnings("unchecked")
public <T> void updateAll(List<T> objects) {
assertNotClosed();
assertNotNull(objects);
if (!objects.isEmpty())
this.objectFilter.updateAll((List<Object>) objects);
if (!objects.isEmpty()) {
for (T object : objects) {
PersistenceContext<T> ctx = createCtx(object);
ctx.setObject(object);
this.objectFilter.update(object.getClass().getName(), ctx);
}
}
}
public <T> void remove(T object) {
assertNotClosed();
assertNotNull(object);
this.objectFilter.remove(object);
PersistenceContext<T> ctx = createCtx(object);
ctx.setObject(object);
this.objectFilter.remove(object.getClass().getName(), ctx);
}
@SuppressWarnings("unchecked")
public <T> void removeAll(List<T> objects) {
assertNotClosed();
assertNotNull(objects);
if (!objects.isEmpty())
this.objectFilter.removeAll((List<Object>) objects);
if (!objects.isEmpty()) {
for (T object : objects) {
PersistenceContext<T> ctx = createCtx(object);
ctx.setObject(object);
this.objectFilter.remove(object.getClass().getName(), ctx);
}
}
}
public <T> void removeById(ObjectRef objectRef) {
assertNotClosed();
assertIsIdRef(objectRef);
this.objectFilter.remove(objectRef);
PersistenceContext<T> ctx = createCtx(objectRef);
this.objectFilter.remove(objectRef.getType(), ctx);
}
public <T> void removeAll(ObjectRef parentRef) {
@ -107,9 +128,8 @@ public class ObjectDao {
for (String id : keySet) {
ObjectRef childRef = parentRef.getChildIdRef(this.tx, id);
PersistenceContext<T> childCtx = childRef.<T> createPersistenceContext(this.tx);
this.objectFilter.remove(childCtx);
PersistenceContext<T> ctx = createCtx(childRef);
this.objectFilter.remove(childRef.getType(), ctx);
}
}
@ -160,6 +180,17 @@ public class ObjectDao {
return size;
}
private <T> PersistenceContext<T> createCtx(T object) {
return this.ctxFactoryDelegator.<T> getCtxFactory(object.getClass()).createCtx(this.tx.getObjectRefCache(),
object);
}
private <T> PersistenceContext<T> createCtx(ObjectRef objectRef) {
String type = objectRef.getType();
PersistenceContextFactory<T> ctxFactory = this.ctxFactoryDelegator.<T> getCtxFactory(type);
return ctxFactory.createCtx(objectRef);
}
private void assertNotClosed() {
if (!this.tx.isOpen())
throw new IllegalStateException("Transaction has been closed and thus no operation can be performed!"); //$NON-NLS-1$

View File

@ -41,8 +41,11 @@ public class PersistenceContextFactoryDelegator {
public void registerPersistenceContextFactory(Class<?> classType, String type,
PersistenceContextFactory<?> ctxFactory) {
this.contextFactoryCacheByClass.put(classType, ctxFactory);
this.contextFactoryCacheByType.put(type, ctxFactory);
if (!classType.getName().equals(type))
this.contextFactoryCacheByType.put(classType.getName(), ctxFactory);
}
public <T> PersistenceContextFactory<T> getCtxFactory(Class<?> classType) {

View File

@ -23,7 +23,7 @@ package ch.eitchnet.xmlpers.api;
import java.util.Properties;
import ch.eitchnet.xmlpers.impl.DefaultXmlPersistenceManager;
import ch.eitchnet.xmlpers.impl.DefaultPersistenceManager;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
@ -33,7 +33,7 @@ public class PersistenceManagerLoader {
public static PersistenceManager load(Properties properties) {
DefaultXmlPersistenceManager persistenceManager = new DefaultXmlPersistenceManager();
DefaultPersistenceManager persistenceManager = new DefaultPersistenceManager();
persistenceManager.initialize(properties);
return persistenceManager;
}

View File

@ -43,9 +43,9 @@ import ch.eitchnet.xmlpers.objref.ObjectReferenceCache;
* @author Robert von Burg <eitch@eitchnet.ch>
*
*/
public class DefaultXmlPersistenceManager implements PersistenceManager {
public class DefaultPersistenceManager implements PersistenceManager {
protected static final Logger logger = LoggerFactory.getLogger(DefaultXmlPersistenceManager.class);
protected static final Logger logger = LoggerFactory.getLogger(DefaultPersistenceManager.class);
protected boolean initialized;
protected boolean verbose;
@ -58,7 +58,7 @@ public class DefaultXmlPersistenceManager implements PersistenceManager {
if (this.initialized)
throw new IllegalStateException("Already initialized!"); //$NON-NLS-1$
String context = DefaultXmlPersistenceManager.class.getSimpleName();
String context = DefaultPersistenceManager.class.getSimpleName();
// get verbose flag
boolean verbose = PropertiesHelper.getPropertyBool(properties, context, PersistenceConstants.PROP_VERBOSE,
@ -78,7 +78,7 @@ public class DefaultXmlPersistenceManager implements PersistenceManager {
}
private void validateBasePath(Properties properties) {
String context = DefaultXmlPersistenceManager.class.getSimpleName();
String context = DefaultPersistenceManager.class.getSimpleName();
String basePath = PropertiesHelper.getProperty(properties, context, PersistenceConstants.PROP_BASEPATH, null);
// validate base path exists and is writable

View File

@ -35,7 +35,6 @@ import ch.eitchnet.xmlpers.api.IoMode;
import ch.eitchnet.xmlpers.api.MetadataDao;
import ch.eitchnet.xmlpers.api.ObjectDao;
import ch.eitchnet.xmlpers.api.PersistenceContext;
import ch.eitchnet.xmlpers.api.PersistenceContextFactoryDelegator;
import ch.eitchnet.xmlpers.api.PersistenceRealm;
import ch.eitchnet.xmlpers.api.PersistenceTransaction;
import ch.eitchnet.xmlpers.api.TransactionCloseStrategy;
@ -143,10 +142,8 @@ public class DefaultPersistenceTransaction implements PersistenceTransaction {
logger.info(removed.size() + " objects removed in this tx."); //$NON-NLS-1$
for (Object object : removed) {
PersistenceContextFactoryDelegator ctxFactoryDelegator = this.realm.getCtxFactoryDelegator();
PersistenceContext<Object> ctx = ctxFactoryDelegator.getCtxFactory(object.getClass())
.createCtx(this.realm.getObjectRefCache(), object);
ctx.setObject(object);
@SuppressWarnings("unchecked")
PersistenceContext<Object> ctx = (PersistenceContext<Object>) object;
this.fileDao.performDelete(ctx);
}
}
@ -160,11 +157,8 @@ public class DefaultPersistenceTransaction implements PersistenceTransaction {
logger.info(updated.size() + " objects updated in this tx."); //$NON-NLS-1$
for (Object object : updated) {
PersistenceContextFactoryDelegator ctxFactoryDelegator = this.realm.getCtxFactoryDelegator();
PersistenceContext<Object> ctx = ctxFactoryDelegator.getCtxFactory(object.getClass())
.createCtx(this.realm.getObjectRefCache(), object);
ctx.setObject(object);
@SuppressWarnings("unchecked")
PersistenceContext<Object> ctx = (PersistenceContext<Object>) object;
this.fileDao.performUpdate(ctx);
}
}
@ -178,11 +172,8 @@ public class DefaultPersistenceTransaction implements PersistenceTransaction {
logger.info(added.size() + " objects added in this tx."); //$NON-NLS-1$
for (Object object : added) {
PersistenceContextFactoryDelegator ctxFactoryDelegator = this.realm.getCtxFactoryDelegator();
PersistenceContext<Object> ctx = ctxFactoryDelegator.getCtxFactory(object.getClass())
.createCtx(this.realm.getObjectRefCache(), object);
ctx.setObject(object);
@SuppressWarnings("unchecked")
PersistenceContext<Object> ctx = (PersistenceContext<Object>) object;
this.fileDao.performCreate(ctx);
}
}

View File

@ -28,6 +28,8 @@ public abstract class ObjectRef extends LockableObject {
public abstract boolean isLeaf();
public abstract String getType();
public abstract ObjectRef getParent(PersistenceTransaction tx);
public abstract ObjectRef getChildIdRef(PersistenceTransaction tx, String id);
@ -37,4 +39,9 @@ public abstract class ObjectRef extends LockableObject {
public abstract File getPath(PathBuilder pathBuilder);
public abstract <T> PersistenceContext<T> createPersistenceContext(PersistenceTransaction tx);
@Override
public String toString() {
return getName();
}
}

View File

@ -6,6 +6,8 @@ public class RefNameCreator {
protected static final String SLASH = "/"; //$NON-NLS-1$
// FIXME validate each name part that it is a valid literal for file names...
public static String createRootName(String realmName) {
assertRealmName(realmName);
return SLASH + realmName + SLASH;
@ -21,7 +23,7 @@ public class RefNameCreator {
assertRealmName(realmName);
assertType(type);
assertId(id);
return SLASH + realmName + SLASH + type + SLASH + id + SLASH;
return SLASH + realmName + SLASH + type + SLASH + id;
}
public static String createSubTypeName(String realmName, String type, String subType) {
@ -36,7 +38,7 @@ public class RefNameCreator {
assertType(type);
assertSubType(subType);
assertId(id);
return SLASH + realmName + SLASH + type + SLASH + subType + SLASH + id + SLASH;
return SLASH + realmName + SLASH + type + SLASH + subType + SLASH + id;
}
private static void assertRealmName(String realmName) {

View File

@ -23,6 +23,12 @@ public class RootRef extends ObjectRef {
return false;
}
@Override
public String getType() {
String msg = MessageFormat.format("RootRef has no type: {0}", getName()); //$NON-NLS-1$
throw new UnsupportedOperationException(msg);
}
@Override
public ObjectRef getParent(PersistenceTransaction tx) {
String msg = MessageFormat.format("RootRef has no parent: {0}", getName()); //$NON-NLS-1$

View File

@ -1,62 +0,0 @@
/*
* Copyright (c) 2012, Robert von Burg
*
* All rights reserved.
*
* This file is part of the XXX.
*
* XXX 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 3 of the License,
* or (at your option) any later version.
*
* XXX 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 XXX. If not, see
* <http://www.gnu.org/licenses/>.
*/
package ch.eitchnet.xmlpers.test.impl;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import ch.eitchnet.xmlpers.test.model.Book;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*
*/
@SuppressWarnings("nls")
public class BookDomDao {
public Element serializeToDom(Book book, Document document) {
Element element = document.createElement("Book");
document.appendChild(element);
element.setAttribute("id", Long.toString(book.getId()));
element.setAttribute("title", book.getTitle());
element.setAttribute("author", book.getAuthor());
element.setAttribute("press", book.getPress());
element.setAttribute("price", Double.toString(book.getPrice()));
return element;
}
public Book parseFromDom(Element element) {
String idS = element.getAttribute("id");
long id = Long.parseLong(idS);
String title = element.getAttribute("title");
String author = element.getAttribute("author");
String press = element.getAttribute("press");
String priceS = element.getAttribute("price");
double price = Double.parseDouble(priceS);
Book book = new Book(id, title, author, press, price);
return book;
}
}

View File

@ -21,39 +21,67 @@
*/
package ch.eitchnet.xmlpers.test.impl;
import javax.xml.parsers.DocumentBuilder;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import ch.eitchnet.xmlpers.api.DomParser;
import ch.eitchnet.xmlpers.test.model.Book;
import ch.eitchnet.xmlpers.util.DomUtil;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*
*
*/
public class BookDomParser implements DomParser<Book> {
private Book book;
@Override
public Book getObject() {
// TODO Auto-generated method stub
return null;
return this.book;
}
@Override
public void setObject(Book object) {
// TODO Auto-generated method stub
this.book = object;
}
@SuppressWarnings("nls")
@Override
public Document toDom() {
// TODO Auto-generated method stub
return null;
DocumentBuilder documentBuilder = DomUtil.createDocumentBuilder();
Document document = documentBuilder.getDOMImplementation().createDocument(null, null, null);
Element rootElement = document.createElement("Book");
document.appendChild(rootElement);
rootElement.setAttribute("id", Long.toString(this.book.getId()));
rootElement.setAttribute("title", this.book.getTitle());
rootElement.setAttribute("author", this.book.getAuthor());
rootElement.setAttribute("press", this.book.getPress());
rootElement.setAttribute("price", Double.toString(this.book.getPrice()));
return document;
}
@SuppressWarnings("nls")
@Override
public void fromDom(Document document) {
// TODO Auto-generated method stub
Element rootElement = document.getDocumentElement();
String idS = rootElement.getAttribute("id");
long id = Long.parseLong(idS);
String title = rootElement.getAttribute("title");
String author = rootElement.getAttribute("author");
String press = rootElement.getAttribute("press");
String priceS = rootElement.getAttribute("price");
double price = Double.parseDouble(priceS);
Book book = new Book(id, title, author, press, price);
this.book = book;
}
}

View File

@ -1,84 +0,0 @@
/*
* Copyright (c) 2012, Robert von Burg
*
* All rights reserved.
*
* This file is part of the XXX.
*
* XXX 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 3 of the License,
* or (at your option) any later version.
*
* XXX 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 XXX. If not, see
* <http://www.gnu.org/licenses/>.
*/
package ch.eitchnet.xmlpers.test.impl;
import javax.xml.stream.XMLStreamException;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import ch.eitchnet.xmlpers.api.XmlPersistenceStreamWriter;
import ch.eitchnet.xmlpers.test.model.Book;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*
*/
@SuppressWarnings("nls")
public class BookSaxDao {
private Book book;
public void write(XmlPersistenceStreamWriter writer) throws XMLStreamException {
writer.writeEmptyElement("Book");
writer.writeAttribute("id", Long.toString(this.book.getId()));
writer.writeAttribute("title", this.book.getTitle());
writer.writeAttribute("author", this.book.getAuthor());
writer.writeAttribute("press", this.book.getPress());
writer.writeAttribute("price", Double.toString(this.book.getPrice()));
}
private class BookDefaultHandler extends DefaultHandler {
private Book book;
public BookDefaultHandler() {
// default constructor
}
public Book getBook() {
return this.book;
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
switch (qName) {
case "Book":
String idS = attributes.getValue("id");
long id = Long.parseLong(idS);
Book book = new Book(id);
book.setTitle(attributes.getValue("title"));
book.setAuthor(attributes.getValue("author"));
book.setPress(attributes.getValue("press"));
String priceS = attributes.getValue("price");
double price = Double.parseDouble(priceS);
book.setPrice(price);
this.book = book;
break;
default:
throw new IllegalArgumentException("The element '" + qName + "' is unhandled!");
}
}
}
}

View File

@ -23,6 +23,8 @@ package ch.eitchnet.xmlpers.test.impl;
import javax.xml.stream.XMLStreamException;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import ch.eitchnet.xmlpers.api.SaxParser;
@ -31,32 +33,59 @@ import ch.eitchnet.xmlpers.test.model.Book;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*
*
*/
public class BookSaxParser implements SaxParser<Book> {
public class BookSaxParser extends DefaultHandler implements SaxParser<Book> {
private Book book;
@Override
public Book getObject() {
// TODO Auto-generated method stub
return null;
return this.book;
}
@Override
public void setObject(Book object) {
// TODO Auto-generated method stub
this.book = object;
}
@Override
public DefaultHandler getDefaultHandler() {
// TODO Auto-generated method stub
return null;
return this;
}
@SuppressWarnings("nls")
@Override
public void write(XmlPersistenceStreamWriter xmlWriter) throws XMLStreamException {
// TODO Auto-generated method stub
public void write(XmlPersistenceStreamWriter writer) throws XMLStreamException {
writer.writeEmptyElement("Book");
writer.writeAttribute("id", Long.toString(this.book.getId()));
writer.writeAttribute("title", this.book.getTitle());
writer.writeAttribute("author", this.book.getAuthor());
writer.writeAttribute("press", this.book.getPress());
writer.writeAttribute("price", Double.toString(this.book.getPrice()));
}
@SuppressWarnings("nls")
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
switch (qName) {
case "Book":
String idS = attributes.getValue("id");
long id = Long.parseLong(idS);
Book book = new Book(id);
book.setTitle(attributes.getValue("title"));
book.setAuthor(attributes.getValue("author"));
book.setPress(attributes.getValue("press"));
String priceS = attributes.getValue("price");
double price = Double.parseDouble(priceS);
book.setPrice(price);
this.book = book;
break;
default:
throw new IllegalArgumentException("The element '" + qName + "' is unhandled!");
}
}
}

View File

@ -1,86 +0,0 @@
/*
* Copyright (c) 2012
*
* This file is part of ch.eitchnet.java.xmlpers
*
* ch.eitchnet.java.xmlpers is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ch.eitchnet.java.xmlpers 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with ch.eitchnet.java.xmlpers. If not, see <http://www.gnu.org/licenses/>.
*
*/
package ch.eitchnet.xmlpers.test.impl;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import ch.eitchnet.xmlpers.test.model.Parameter;
import ch.eitchnet.xmlpers.test.model.Resource;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*
*/
@SuppressWarnings("nls")
public class ResourceDomDao {
public Element serializeToDom(Resource resource, Document document) {
Element element = document.createElement("Resource");
document.appendChild(element);
element.setAttribute("id", resource.getId());
element.setAttribute("name", resource.getName());
element.setAttribute("type", resource.getType());
for (String paramId : resource.getParameterKeySet()) {
Parameter param = resource.getParameterBy(paramId);
Element paramElement = document.createElement("Parameter");
element.appendChild(paramElement);
paramElement.setAttribute("id", param.getId());
paramElement.setAttribute("name", param.getName());
paramElement.setAttribute("type", param.getType());
paramElement.setAttribute("value", param.getValue());
}
return element;
}
public Resource parseFromDom(Element element) {
String id = element.getAttribute("id");
String name = element.getAttribute("name");
String type = element.getAttribute("type");
Resource resource = new Resource(id, name, type);
NodeList children = element.getChildNodes();
for (int i = 0; i < children.getLength(); i++) {
Node item = children.item(i);
if (!item.getNodeName().equals("Parameter"))
continue;
Element paramElement = (Element) item;
String paramId = paramElement.getAttribute("id");
String paramName = paramElement.getAttribute("name");
String paramType = paramElement.getAttribute("type");
String paramValue = paramElement.getAttribute("value");
Parameter param = new Parameter(paramId, paramName, paramType, paramValue);
resource.addParameter(param);
}
return resource;
}
}

View File

@ -1,92 +0,0 @@
/*
* Copyright (c) 2012
*
* This file is part of ch.eitchnet.java.xmlpers
*
* ch.eitchnet.java.xmlpers is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ch.eitchnet.java.xmlpers 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with ch.eitchnet.java.xmlpers. If not, see <http://www.gnu.org/licenses/>.
*
*/
package ch.eitchnet.xmlpers.test.impl;
import javax.xml.stream.XMLStreamException;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import ch.eitchnet.xmlpers.api.XmlPersistenceStreamWriter;
import ch.eitchnet.xmlpers.test.model.Parameter;
import ch.eitchnet.xmlpers.test.model.Resource;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*
*/
@SuppressWarnings("nls")
public class ResourceSaxDao {
private Resource resource;
public void write(XmlPersistenceStreamWriter writer) throws XMLStreamException {
writer.writeElement("Resource");
writer.writeAttribute("id", this.resource.getId());
writer.writeAttribute("name", this.resource.getName());
writer.writeAttribute("type", this.resource.getType());
for (String paramId : this.resource.getParameterKeySet()) {
Parameter param = this.resource.getParameterBy(paramId);
writer.writeElement("Parameter");
writer.writeAttribute("id", param.getId());
writer.writeAttribute("name", param.getName());
writer.writeAttribute("type", param.getType());
writer.writeAttribute("value", param.getValue());
}
}
private class ResourceDefaultHandler extends DefaultHandler {
private Resource resource;
public ResourceDefaultHandler() {
// default constructor
}
public Resource getResource() {
return this.resource;
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
switch (qName) {
case "Resource":
String id = attributes.getValue("id");
String name = attributes.getValue("name");
String type = attributes.getValue("type");
Resource resource = new Resource(id, name, type);
this.resource = resource;
break;
case "Parameter":
id = attributes.getValue("id");
name = attributes.getValue("name");
type = attributes.getValue("type");
String value = attributes.getValue("value");
Parameter param = new Parameter(id, name, type, value);
this.resource.addParameter(param);
break;
default:
throw new IllegalArgumentException("The element '" + qName + "' is unhandled!");
}
}
}
}

View File

@ -70,6 +70,11 @@ public class ModelBuilder {
return book;
}
public static Book createBook(long id, String title, String author, String press, double price) {
Book book = new Book(id, title, author, press, price);
return book;
}
public static void updateBook(Book book) {
book.setPress(BOOK_PRESS_2);
}