// SV prefix URIs
String svURI = null;
String exoURI = null;
PlainChangesLog changes = new PlainChangesLogImpl();
// SVNodeData currentNode = null;
Stack<SVNodeData> parents = new Stack<SVNodeData>();
SVPropertyData currentProperty = null;
ValueWriter propertyValue = null;
int propertyType = -1;
while (reader.hasNext())
{
int eventCode = reader.next();
switch (eventCode)
{
case StartElement.START_ELEMENT : {
String lname = reader.getLocalName();
String prefix = reader.getPrefix();
if (Constants.NS_SV_PREFIX.equals(prefix))
{
// read prefixes URIes from source SV XML
if (svURI == null)
{
svURI = reader.getNamespaceURI(Constants.NS_SV_PREFIX);
exoURI = reader.getNamespaceURI(Constants.NS_EXO_PREFIX);
}
if (Constants.SV_NODE.equals(lname))
{
String svName = reader.getAttributeValue(svURI, Constants.SV_NAME);
String exoId = reader.getAttributeValue(exoURI, Constants.EXO_ID);
if (svName != null && exoId != null)
{
// create subnode
QPath currentPath;
String parentId;
int orderNumber;
if (parents.size() > 0)
{
// path to a new node
SVNodeData parent = parents.peek();
InternalQName name = locationFactory.parseJCRName(svName).getInternalName();
int[] chi = parent.addChildNode(name);
orderNumber = chi[0];
int index = chi[1];
currentPath = QPath.makeChildPath(parent.getQPath(), name, index);
parentId = parent.getIdentifier();
}
else
{
// root
currentPath = Constants.ROOT_PATH;
parentId = null;
orderNumber = 0;
// register namespaces from jcr:root node
for (int i = 0; i < reader.getNamespaceCount(); i++)
{
String nsp = reader.getNamespacePrefix(i);
try
{
namespaceRegistry.getURI(nsp);
}
catch (NamespaceException e)
{
namespaceRegistry.registerNamespace(nsp, reader.getNamespaceURI(i));
}
}
}
SVNodeData currentNode = new SVNodeData(currentPath, exoId, parentId, 0, orderNumber);
// push current node as parent
parents.push(currentNode);
// add current node to changes log.
// add node, no event fire, persisted, internally created, root is ancestor to save
changes.add(new ItemState(currentNode, ItemState.ADDED, false, Constants.ROOT_PATH, true,
true));
}
else
log.warn("Node skipped name=" + svName + " id=" + exoId + ". Context node "
+ (parents.size() > 0 ? parents.peek().getQPath().getAsString() : "/"));
}
else if (Constants.SV_PROPERTY.equals(lname))
{
String svName = reader.getAttributeValue(svURI, Constants.SV_NAME);
String exoId = reader.getAttributeValue(exoURI, Constants.EXO_ID);
String svType = reader.getAttributeValue(svURI, Constants.SV_TYPE);
if (svName != null && svType != null && exoId != null)
{
if (parents.size() > 0)
{
SVNodeData parent = parents.peek();
QPath currentPath =
QPath.makeChildPath(parent.getQPath(), locationFactory.parseJCRName(svName)
.getInternalName());
try
{
propertyType = PropertyType.valueFromName(svType);
}
catch (IllegalArgumentException e)
{
propertyType = ExtendedPropertyType.valueFromName(svType);
}
// exo:multivalued optional, assigned for multivalued properties only
String exoMultivalued = reader.getAttributeValue(exoURI, Constants.EXO_MULTIVALUED);
currentProperty =
new SVPropertyData(currentPath, exoId, 0, propertyType, parent.getIdentifier(),
("true".equals(exoMultivalued) ? true : false));
}
else
log.warn("Property can'b be first name=" + svName + " type=" + svType + " id=" + exoId
+ ". Node should be prior. Context node "
+ (parents.size() > 0 ? parents.peek().getQPath().getAsString() : "/"));
}
else
log.warn("Property skipped name=" + svName + " type=" + svType + " id=" + exoId
+ ". Context node "
+ (parents.size() > 0 ? parents.peek().getQPath().getAsString() : "/"));
}
else if (Constants.SV_VALUE.equals(lname) && propertyType != -1)
{
if (propertyType == PropertyType.BINARY)
propertyValue = new BinaryValueWriter();
else
propertyValue = new StringValueWriter();
}
}
break;
}
case StartElement.CHARACTERS : {
if (propertyValue != null)
{
// read property value text
propertyValue.write(reader.getText());
}
break;
}
case StartElement.END_ELEMENT : {
String lname = reader.getLocalName();
String prefix = reader.getPrefix();
if (Constants.NS_SV_PREFIX.equals(prefix))
{
if (Constants.SV_NODE.equals(lname))
{
// change current context
// - pop parent from the stack
SVNodeData parent = parents.pop();
if (parent.getMixinTypeNames() == null)
{
// mixins cannot be null
parent.setMixinTypeNames(new InternalQName[0]);
}
}
else if (Constants.SV_PROPERTY.equals(lname))
{
// apply property to the current node and changes log
if (currentProperty != null)
{
SVNodeData parent = parents.peek();
// check NodeData specific properties
if (currentProperty.getQPath().getName().equals(Constants.JCR_PRIMARYTYPE))
{
parent.setPrimartTypeName(InternalQName.parse(new String(currentProperty.getValues().get(
0).getAsByteArray())));
}
else if (currentProperty.getQPath().getName().equals(Constants.JCR_MIXINTYPES))
{
InternalQName[] mixins = new InternalQName[currentProperty.getValues().size()];
for (int i = 0; i < currentProperty.getValues().size(); i++)
{
mixins[i] =
InternalQName
.parse(new String(currentProperty.getValues().get(i).getAsByteArray()));
}
parent.setMixinTypeNames(mixins);
}
// add property, no event fire, persisted, internally created, root is ancestor to
// save
changes.add(new ItemState(currentProperty, ItemState.ADDED, false, Constants.ROOT_PATH,
true, true));
// reset property context
propertyType = -1;
currentProperty = null;