/**
* Copyright 2004-2016 Riccardo Solmi. All rights reserved.
* This file is part of the Whole Platform.
*
* The Whole Platform 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.
*
* The Whole Platform 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 the Whole Platform. If not, see <http://www.gnu.org/licenses/>.
*/
/**
*
*/
package org.whole.lang.xsd.builders;
import static org.whole.lang.xml.reflect.XmlEntityDescriptorEnum.NameSpace;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import org.whole.lang.bindings.BindingManagerFactory;
import org.whole.lang.bindings.IBindingManager;
import org.whole.lang.iterators.IEntityIterator;
import org.whole.lang.iterators.IteratorFactory;
import org.whole.lang.matchers.Matcher;
import org.whole.lang.model.IEntity;
import org.whole.lang.model.adapters.IEntityAdapter;
import org.whole.lang.util.DataTypeUtils;
import org.whole.lang.xml.visitors.XmlTraverseAllVisitor;
import org.whole.lang.xsd.builders.utils.AttributesMatcherFactory;
import org.whole.lang.xsd.util.NamespaceUtils;
/**
* @author Enrico Persiani
*/
final class XmlFragmentNormalizer extends XmlTraverseAllVisitor {
private boolean calculateNeededNamespaces;
private Set<String> neededNamespaces;
private IBindingManager ns = BindingManagerFactory.instance.createBindingManager();
public XmlFragmentNormalizer() {
this(false);
}
public XmlFragmentNormalizer(boolean calculateNeededNamespaces) {
this.calculateNeededNamespaces = calculateNeededNamespaces;
this.neededNamespaces = calculateNeededNamespaces ? new HashSet<String>() : Collections.<String>emptySet();
}
public boolean visitAdapter(IEntityAdapter entity) {
if (calculateNeededNamespaces && Matcher.match(NameSpace, entity))
updateNeededNamespaces(NamespaceUtils.DEFAULT_NAMESPACE_PREFIX);
return super.visitAdapter(entity);
}
public void visit(org.whole.lang.xml.model.Element entity) {
if (calculateNeededNamespaces) {
ns.wEnterScope();
IEntityIterator<IEntity> iterator = IteratorFactory.childMatcherIterator()
.withPattern(AttributesMatcherFactory.matchNamespaceDeclaration(ns));
iterator.reset(entity.getAttributes());
while (iterator.hasNext()) {
iterator.next();
String uri = ns.wStringValue("uri");
if (ns.wIsSet("xmlns"))
ns.wDefValue(ns.wStringValue("xmlns"), uri);
else
NamespaceUtils.redefineDefaultNamespace(ns, uri);
}
super.visit(entity);
ns.wExitScope();
} else
super.visit(entity);
}
public void visit(org.whole.lang.xml.model.CharData entity) {
if (entity.getValue().length() == 0)
entity.wGetParent().wRemove(entity);
}
public void visit(org.whole.lang.xml.model.NameSpace entity) {
if (calculateNeededNamespaces) {
String prefix = DataTypeUtils.getAsPersistenceString(entity);
if (!"xmlns".equals(prefix))
updateNeededNamespaces(prefix);
}
}
private void updateNeededNamespaces(String prefix) {
if (!ns.wIsSet(prefix))
neededNamespaces.add(prefix);
}
public Set<String> getNeededNamespaces() {
return neededNamespaces;
}
}