Customizando Componentes Individuais
Até o momento, você viu somente exemplos de customizações que se aplicam a todo o conjunto de esquemas ou a esquemas individuais. Você também pode customizar a manipulação de componentes específicos de CodeGen em uma definição de esquema, incluindo definições globais e itens integrados às definições globais. As customizações disponíveis incluem eliminar o componente do modelo de dados, alterando a classe ou o nome do valor usado para o componente e alterando o tipo de esquema do componente.
As customizações para eliminar componentes do modelo de dados não são muito úteis se você controlar o esquema
— nesse caso, sempre será mais simples apenas alterar o esquema diretamente. Mas esquemas de troca de de dados corporativos frequentemente incluem componentes especializados que podem não ser apropriados para aplicativos específicos usando esses esquemas e esses esquemas geralmente não estão sob seu controle. Usar customizações nesse caso permite simplificar seu modelo de dados sem tocar os esquemas fornecidos.
Customizações de Componentes
As customizações para componentes de esquema funcionam associando um elemento de customização ao elementos de definição de esquema que representa o componente.
Você pode usar diversas abordagens diferentes para estabelecer a associação entre a customização e o elemento do esquema, pois uma abordagem pode ser mais conveniente do que outra em uma situação específica.
Uma parte da associação é fixa, no entanto: o nome do elemento de customização deve sempre corresponder ao nome do elemento do componente do esquema. Portanto, para customizar uma definição
<xs:element> em um esquema, por exemplo, você precisa usar um elemento de customização
<element (sem nenhum namespace).
A Listagem 15 mostra uma definição de um dos outros esquemas referidos por TimeCard, que é uma boa amostra para demonstrar customização de componentes individuais. O PersonNameType consiste em diversos elementos xs:string simples, juntamente com alguns outros elementos com estrutura complexa. Como ocorre, os documentos de teste usados no código do tutorial não incluem nenhuma instância dos elementos Affix ou AlternateScript desse tipo, portanto, são bons candidatos para eliminar para simplificar o modelo de dados gerado.
Listagem 15. Esquema PersonName
<xsd:complexType name="PersonNameType">
<xsd:sequence>
<xsd:element name="FormattedName" type="xsd:string" minOccurs="0"/>
<xsd:element name="LegalName" type="xsd:string" minOccurs="0"/>
<xsd:element name="GivenName" type="xsd:string" minOccurs="0" maxOccurs="unbounded"/>
<xsd:element name="PreferredGivenName" type="xsd:string" minOccurs="0"/>
<xsd:element name="MiddleName" type="xsd:string" minOccurs="0"/>
<xsd:element name="FamilyName" minOccurs="0" maxOccurs="unbounded">
<xsd:complexType>
...
</xsd:complexType>
</xsd:element>
<xsd:element name="Affix" minOccurs="0" maxOccurs="unbounded">
<xsd:complexType>
...
</xsd:complexType>
</xsd:element>
<xsd:element name="AlternateScript" minOccurs="0" maxOccurs="unbounded">
<xsd:complexType>
...
</xsd:complexType>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="script" type="xsd:string"/>
</xsd:complexType> |
A Listagem 16 mostra uma maneira de definir customizações para eliminar os elementos Affix eAlternateScript do modelo de dados. Essa abordagem usa uma especificação de caminho, que é um conjunto de instruções como XPath para navegar pela estrutura de definição de esquema. As etapas do caminho são separadas por caracteres barra (/) e as etapas que correspondem a componentes denominados da definição de esquema (tipo global, grupo ou definições attributeGroup , os definições de elementos ou atributos, sendo globais ou não) podem usar um predicado element or attribute definitions whether global or not) can use an [@name=...] para destacar uma instância específica do tipo de componente.
Listagem 16. Customização Direta para Componentes Desnecessários
<schema-set ...>
<schema name="PersonName.xsd">
<element path="complexType[@name=PersonNameType]/sequence/element[@name=Affix]"
ignore="true"/>
<element path=
"complexType[@name=PersonNameType]/sequence/element[@name=AlternateScript]"
ignore="true"/>
</schema>
</schema-set> |
Na Listagem 16, cada caminho está escrito por extenso, a partir do nível do esquema. Você também pode usar curingas nos caminhos. O curinga * como etapa do caminho corresponde a qualquer elemento único na definição de esquema, enquanto que o curinga ** corresponde a um número qualquer de elementos aninhados na definição do esquema. Portanto, em vez de o caminho complexType[@name=PersonNameType]/sequence/element[@name=Affix], você poderia usar complexType[@name=PersonNameType]/*/element[@name=Affix]ou complexType[@name=PersonNameType]/**/element[@name=Affix]. Não poderia usar **/element[@name=Affix], no entanto — CodeGen requer que você identifique explicitamente o componente da definição global envolvido em qualquer customização, como segurança para evitar a aplicação da customização incorretamente.
As customizações do componentes podem ser aninhadas, desde que o aninhamento corresponda à estrutura de definição de esquema.
Nesse caso, cada customização precisa apenas de especificar seu destino em relação à customização contida.
Você também pode usar um atributo name="..." na customização como uma alternativa para um predicado [@name=...] na etapa final de um caminho e pode ignorar o nome do elemento na etapa final (pois deve sempre ser o mesmo que o nome do elemento de customização). Você pode até mesmo evitar o uso de um caminho completamente, usando, em vez disso aninhamento combinado a um atributo de nome. A Listagem 17 mostra as mesmas customizações que a Listagem 16, reestruturada para usar essa abordagem alternativa:
Listagem 17. Customização Aninhada para Componentes Desnecessários
<schema-set ...>
<schema name="PersonName.xsd">
<complexType name="PersonNameType">
<sequence>
<element name="Affix" ignore="true"/>
<element name="AlternateScript" ignore="true"/>
</sequence>
</complexType>
</schema>
</schema-set> |
Simplufucando o Modelo de Dados
Além dos componentes PersonName usados como exemplos na subseção anterior, os esquemas TimeCard têm outros diversos componentes complexos que não são usados nos documentos de amostra incluídos neste tutorial. Usando customizações para eliminar esses componentes não usados, você pode simplificar de forma considerável o modelo de dados gerado. Há também alguns casos em que nomes de valor Java usados por CodeGen não funcionarão bem. Especificamente, casos em que o mesmo nome de elemento é usado repetidamente podem resultar em nomes de valores distintos somente por sufixos de dígitos, dificultando o entendimento do uso apropriado dos valores. Consulte a Listagem 10 para obter um exemplo, onde um par de campos denominados duration e duration1 estão incluídos no código gerado. Você pode usar uma customização para alterar um desses nomes para algo mais significativo.
A Listagem 18 mostra o arquivo custom3.xml do diretório hrxml do código, que inclui todas essas customizações. Isso usa intencionalmente diversas abordagens de identificação de componente discutidas na subseção anterior, com aninhamento, caminho e caminhos combinados com nomes. A customização do nome do valor está na parte inferior, usando um atributo value-name="simpleDuration" para alterar o nome usado para a segunda duração para uma forma mais descritiva.
Listagem 18. Simplificando e Esclarecendo o Modelo de Dados TimeCard
<schema-set xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:tns="http://ns.hr-xml.org/2007-04-15" package="org.hrxml.timecard"
type-substitutions="xs:integer xs:int" generate-all="false">
<name-converter strip-suffixes="Type"/>
<class-decorator class="org.jibx.schema.codegen.extend.CollectionMethodsDecorator"/>
<schema name="UserArea.xsd" excludes="UserArea UserAreaType"/>
<schema name="PersonName.xsd">
<complexType name="PersonNameType">
<sequence>
<element name="Affix" ignore="true"/>
<element name="AlternateScript" ignore="true"/>
</sequence>
</complexType>
</schema>
<schema name="TimeCard.xsd" includes="TimeCard">
<complexType name="TimeCardType">
<element path="**/element[@name=Allowance]" ignore="true"/>
<element path="**/element[@name=PieceWork]" ignore="true"/>
<element path="**/element[@name=TimeEvent]/**/" name="RateOrAmount" ignore="true"/>
<element path="**/choice/[@name=Duration]" value-name="simpleDuration"/>
</complexType>
</schema>
</schema-set> |
É possível usar o destino Ant custgen3 para tentar essa customização com CodeGen ou usar o destino custom3 para executar a sequência completa de geração, compilação, ligação e teste. As customizações reduzem a contagem de classes geradas para 9 classes de nível superior e 10 classes internas, um total de 19. Essa contagem é exatamente metade do número de classe do modelo de dados gerado original sem usar customizações.
|