blob: 7c721cf913f35266b77469f483ce4b5c8f4a8394 [file] [log] [blame]
/*
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.apache.qpid.gentools;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
public class AmqpField implements Printable, NodeAware, VersionConsistencyCheck
{
private final AmqpVersionSet _versionSet = new AmqpVersionSet();
private final AmqpDomainVersionMap _domainMap = new AmqpDomainVersionMap();
private final AmqpOrdinalVersionMap _ordinalMap = new AmqpOrdinalVersionMap();
private final String _name;
private final Generator _generator;
private final Map<AmqpVersion, String> _versionToDomainMap = new HashMap<AmqpVersion, String>();
private final Map<AmqpVersion, Integer> _versionToOrdinalMap = new HashMap<AmqpVersion, Integer>();
public AmqpField(String name, Generator generator)
{
_name = name;
_generator = generator;
}
public boolean addFromNode(Node fieldNode, int ordinal, AmqpVersion version)
throws AmqpParseException, AmqpTypeMappingException
{
_versionSet.add(version);
String domainType;
// Early versions of the spec (8.0) used the "type" attribute instead of "domain" for some fields.
try
{
domainType = _generator.prepareDomainName(Utils.getNamedAttribute(fieldNode, Utils.ATTRIBUTE_DOMAIN));
}
catch (AmqpParseException e)
{
domainType = _generator.prepareDomainName(Utils.getNamedAttribute(fieldNode, Utils.ATTRIBUTE_TYPE));
}
AmqpVersionSet thisVersionList = _domainMap.get(domainType);
if (thisVersionList == null) // First time, create new entry
{
thisVersionList = new AmqpVersionSet();
_domainMap.put(domainType, thisVersionList);
}
_versionToDomainMap.put(version, domainType);
_versionToOrdinalMap.put(version, ordinal);
thisVersionList.add(version);
thisVersionList = _ordinalMap.get(ordinal);
if (thisVersionList == null) // First time, create new entry
{
thisVersionList = new AmqpVersionSet();
_ordinalMap.put(ordinal, thisVersionList);
}
thisVersionList.add(version);
NodeList nList = fieldNode.getChildNodes();
for (int i = 0; i < nList.getLength(); i++)
{
Node child = nList.item(i);
if (child.getNodeName().compareTo(Utils.ELEMENT_CODEGEN) == 0)
{
String value = Utils.getNamedAttribute(child, Utils.ATTRIBUTE_VALUE);
if (value.compareTo("no-gen") == 0)
{
return false;
}
}
}
return true;
}
public void removeVersion(AmqpVersion version)
{
_domainMap.removeVersion(version);
_ordinalMap.removeVersion(version);
_versionSet.remove(version);
}
public boolean isCodeTypeConsistent(LanguageConverter converter)
throws AmqpTypeMappingException
{
if (_domainMap.size() == 1)
{
return true; // By definition
}
ArrayList<String> codeTypeList = new ArrayList<String>();
for (String thisDomainName : _domainMap.keySet())
{
AmqpVersionSet versionSet = _domainMap.get(thisDomainName);
String codeType = converter.getGeneratedType(thisDomainName, versionSet.first());
if (!codeTypeList.contains(codeType))
{
codeTypeList.add(codeType);
}
}
return codeTypeList.size() == 1;
}
public boolean isConsistent(Generator generator)
throws AmqpTypeMappingException
{
if (!isCodeTypeConsistent(generator))
{
return false;
}
if (_ordinalMap.size() != 1)
{
return false;
}
// Since the various doamin names map to the same code type, add the version occurrences
// across all domains to see we have all possible versions covered
int vCntr = 0;
for (String thisDomainName : _domainMap.keySet())
{
vCntr += _domainMap.get(thisDomainName).size();
}
return vCntr == generator.getVersionSet().size();
}
public boolean isTypeAndNameConsistent(Generator generator)
throws AmqpTypeMappingException
{
if (!isCodeTypeConsistent(generator))
{
return false;
}
// Since the various doamin names map to the same code type, add the version occurrences
// across all domains to see we have all possible versions covered
int vCntr = 0;
for (String thisDomainName : _domainMap.keySet())
{
vCntr += _domainMap.get(thisDomainName).size();
}
return vCntr == getVersionSet().size();
}
public void print(PrintStream out, int marginSize, int tabSize)
{
String margin = Utils.createSpaces(marginSize);
out.println(margin + "[F] " + _name + ": " + _versionSet);
for (Integer thisOrdinal : _ordinalMap.keySet())
{
AmqpVersionSet versionList = _ordinalMap.get(thisOrdinal);
out.println(margin + " [O] " + thisOrdinal + " : " + versionList.toString());
}
for (String thisDomainName : _domainMap.keySet())
{
AmqpVersionSet versionList = _domainMap.get(thisDomainName);
out.println(margin + " [D] " + thisDomainName + " : " + versionList.toString());
}
}
public boolean isVersionConsistent(AmqpVersionSet globalVersionSet)
{
if (!_versionSet.equals(globalVersionSet))
{
return false;
}
if (!_domainMap.isVersionConsistent(globalVersionSet))
{
return false;
}
if (!_ordinalMap.isVersionConsistent(globalVersionSet))
{
return false;
}
return true;
}
public boolean isVersionInterfaceConsistent(AmqpVersionSet globalVersionSet)
{
if (!_versionSet.equals(globalVersionSet))
{
return false;
}
if (!_domainMap.isVersionConsistent(globalVersionSet))
{
return false;
}
if (!_ordinalMap.isVersionConsistent(globalVersionSet))
{
return false;
}
return true;
}
public String getDomain(AmqpVersion version)
{
return _versionToDomainMap.get(version);
}
public String getConsistentNativeType()
{
return _generator.getNativeType(_generator.getDomainType(getDomain(_versionSet.first()),_versionSet.first()));
}
public int getOrdinal(AmqpVersion version)
{
return _versionToOrdinalMap.get(version);
}
public AmqpVersionSet getVersionSet()
{
return _versionSet;
}
public AmqpDomainVersionMap getDomainMap()
{
return _domainMap;
}
public AmqpOrdinalVersionMap getOrdinalMap()
{
return _ordinalMap;
}
public String getName()
{
return _name;
}
public LanguageConverter getGenerator()
{
return _generator;
}
public Map<AmqpVersion, String> getVersionToDomainMap()
{
return _versionToDomainMap;
}
public Map<AmqpVersion, Integer> getVersionToOrdinalMap()
{
return _versionToOrdinalMap;
}
}