/*
* $Id: GLSDDocumentModuleChecker.cpp,v 1.8 2006/06/27 13:11:40 ozawa Exp $
*
* Copyright 2005- ONGS Inc. All rights reserved.
*
* author: Masanori OZAWA (ozawa@ongs.co.jp)
* version: $Revision: 1.8 $
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY ONGS INC ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL ONGS INC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are
* those of the authors and should not be interpreted as representing official
* policies, either expressed or implied, of the ONGS Inc.
*
*/
#include "xdtp.h"
#include "modules/GLSDDocumentModuleChecker.h"
#include "XMLTool.h"
using namespace XDTP;
GLSDDocumentModuleChecker::GLSDDocumentModuleChecker()
{
}
GLSDDocumentModuleChecker::~GLSDDocumentModuleChecker()
{
}
/**
* 文書モジュールの正当性をチェックします。
*
* @param aDocument ロードした直後のXMLファイル
* @return 変換処理を中断する場合は false を戻します。
*/
bool GLSDDocumentModuleChecker::checkFormat(xmlDocPtr aDocument)
{
bool result = true;
int count = 0;
int count2 = 0;
int count3 = 0;
XMLTool tool;
xmlNodePtr node;
xmlNodePtr child;
xmlNodePtr root = xmlDocGetRootElement(aDocument);
xmlXPathObjectPtr obj;
xmlXPathObjectPtr children;
xmlXPathObjectPtr tmpobj;
xmlXPathObjectPtr tmpobj2;
xmlNodeSetPtr nodes;
xmlNodeSetPtr childset;
xmlNodeSetPtr tmpobjset;
// alias のチェック
if (!checkAlias(root)) {
return false;
}
// import のチェック
obj = tool.getNodeList(root, "//import");
if (obj) {
nodes = obj->nodesetval;
for (count = 0; result && count < nodes->nodeNr; count++) {
if (!tool.isElement(nodes->nodeTab[count])) continue;
if (!xmlHasProp(nodes->nodeTab[count], (const xmlChar*)"type") ||
!xmlHasProp(nodes->nodeTab[count], (const xmlChar*)"ref"))
{
result = false;
}
}
xmlXPathFreeObject(obj);
if (!result) fprintf(stderr, "%s: GLSDDocumentModuleChecker: bad import." LINE_SEP, APP_NAME);
}
// mark のチェック
obj = (result ? tool.getNodeList(root, "//mark") : NULL);
if (obj) {
nodes = obj->nodesetval;
for (count = 0; result && count < nodes->nodeNr; count++) {
if (!tool.isElement(nodes->nodeTab[count])) continue;
if (!xmlHasProp(nodes->nodeTab[count], (const xmlChar*)"type")) {
result = false;
}
}
xmlXPathFreeObject(obj);
if (!result) fprintf(stderr, "%s: GLSDDocumentModuleChecker: bad mark." LINE_SEP, APP_NAME);
}
// list のチェック
obj = (result ? tool.getNodeList(root, "//list") : NULL);
if (obj) {
nodes = obj->nodesetval;
for (count = 0; result && count < nodes->nodeNr; count++) {
node = nodes->nodeTab[count];
if (!tool.isElement(node)) continue;
result = checkFormat_list(node);
}
xmlXPathFreeObject(obj);
if (!result) fprintf(stderr, "%s: GLSDDocumentModuleChecker: bad list." LINE_SEP, APP_NAME);
}
// thebibliography のチェック
obj = (result ? tool.getNodeList(root, "//thebibliography") : NULL);
if (obj) {
nodes = obj->nodesetval;
for (count = 0; result && count < nodes->nodeNr; count++) {
node = nodes->nodeTab[count];
if (!tool.isElement(node)) continue;
children = tool.getNodeList(node, "./bibitem");
if (!children) {
result = false;
}
else {
childset = children->nodesetval;
if (1 > childset->nodeNr) result = false;
for (count2 = 0; result && count2 < childset->nodeNr; count2++) {
child = childset->nodeTab[count2];
tmpobj = tool.getNodeList(child, "./title");
if (!tmpobj) result = false;
else {
if (0 >= tmpobj->nodesetval->nodeNr) result = false;
xmlXPathFreeObject(tmpobj);
}
tmpobj = tool.getNodeList(child, "./publisher");
if (tmpobj) {
if (1 < tmpobj->nodesetval->nodeNr) result = false;
xmlXPathFreeObject(tmpobj);
}
tmpobj = tool.getNodeList(child, "author | title | publisher | year");
if (tmpobj) {
tmpobjset = tmpobj->nodesetval;
for (count3 = 0; result && count3 < tmpobjset->nodeNr; count3++) {
tmpobj2 = tool.getNodeList(tmpobjset->nodeTab[count3], "./p");
if (!tmpobj2) result = false;
else {
if (1 != tmpobj2->nodesetval->nodeNr) result = false;
xmlXPathFreeObject(tmpobj2);
}
}
xmlXPathFreeObject(tmpobj);
}
}
xmlXPathFreeObject(children);
}
}
xmlXPathFreeObject(obj);
if (!result) fprintf(stderr, "%s: GLSDDocumentModuleChecker: bad thebibliography." LINE_SEP, APP_NAME);
}
// footnote のチェック
obj = (result ? tool.getNodeList(root, "//footnote") : NULL);
if (obj) {
nodes = obj->nodesetval;
for (count = 0; count < nodes->nodeNr; count++) {
if (!tool.isElement(nodes->nodeTab[count])) continue;
children = tool.getNodeList(nodes->nodeTab[count], "./*");
if (children) {
if (0 != children->nodesetval->nodeNr) result = false;
xmlXPathFreeObject(children);
}
}
xmlXPathFreeObject(obj);
if (!result) fprintf(stderr, "%s: GLSDDocumentModuleChecker: bad footnote." LINE_SEP, APP_NAME);
}
// access のチェック
obj = (result ? tool.getNodeList(root, "//access") : NULL);
if (obj) {
nodes = obj->nodesetval;
for (count = 0; result && count < nodes->nodeNr; count++) {
node = nodes->nodeTab[count];
if (!tool.isElement(node)) continue;
if (!xmlHasProp(node, (const xmlChar*)"ref")) {
result = false;
}
children = (result ? tool.getNodeList(node, "./*") : NULL);
if (children) {
if (0 != children->nodesetval->nodeNr) result = false;
xmlXPathFreeObject(children);
}
}
xmlXPathFreeObject(obj);
if (!result) fprintf(stderr, "%s: GLSDDocumentModuleChecker: bad access." LINE_SEP, APP_NAME);
}
// ruby のチェック
obj = (result ? tool.getNodeList(root, "//ruby") : NULL);
if (obj) {
nodes = obj->nodesetval;
for (count = 0; result && count < nodes->nodeNr; count++) {
node = nodes->nodeTab[count];
if (!tool.isElement(node)) continue;
if (!xmlHasProp(node, (const xmlChar*)"rubytext")) {
result = false;
}
children = tool.getNodeList(node, "./*");
if (children) {
if (0 != children->nodesetval->nodeNr) result = false;
xmlXPathFreeObject(children);
}
}
xmlXPathFreeObject(obj);
if (!result) fprintf(stderr, "%s: GLSDDocumentModuleChecker: bad ruby." LINE_SEP, APP_NAME);
}
return result;
}
/**
* aliasエレメントの確認。
*
* @param aDocumentRoot
* XMLのルートノード
*/
bool GLSDDocumentModuleChecker::checkAlias(xmlNodePtr aDocumentRoot)
{
bool result = true;
int count;
XMLTool tool;
xmlNodePtr node;
xmlNodePtr child;
xmlNodeSetPtr nodes;
xmlXPathObjectPtr obj = tool.getNodeList(aDocumentRoot, "//alias");
if (obj) {
nodes = obj->nodesetval;
for (count = 0; result && count < nodes->nodeNr; count++) {
node = nodes->nodeTab[count];
if (!node->parent || xmlStrcmp(node->parent->name, (xmlChar*)"p") != 0)
result = false;
else {
for (child = node->children; result && child; child = child->next) {
if (!tool.isText(child)) result = false;
}
if (result) {
if (0 >= tool.getText(node).length()) result = false;
}
}
}
xmlXPathFreeObject(obj);
}
return result;
}
/**
* list要素の構造をチェックします。
*
* @param aNode 親list要素
* @return 変換処理を中断する場合は false を戻します。
*/
bool GLSDDocumentModuleChecker::checkFormat_list(xmlNodePtr aNode)
{
bool result = true;
int count, count2;
XMLTool tool;
xmlNodePtr node;
xmlNodePtr child;
xmlXPathObjectPtr children;
xmlXPathObjectPtr tmpobj;
xmlNodeSetPtr childset;
xmlNodeSetPtr tmpobjset;
children = tool.getNodeList(aNode, "./item");
if (children) {
childset = children->nodesetval;
for (count = 0; result && count < childset->nodeNr; count++) {
child = childset->nodeTab[count];
// 最低1つのp要素が必要
tmpobj = tool.getNodeList(child, "./p");
if (!tmpobj) result = false;
else {
if (0 >= tmpobj->nodesetval->nodeNr) result = false;
xmlXPathFreeObject(tmpobj);
}
// ネストされたlist要素をチェック
tmpobj = tool.getNodeList(child, "./list");
if (tmpobj) {
tmpobjset = tmpobj->nodesetval;
for (count2 = 0; result && count2 < tmpobjset->nodeNr; count2++) {
node = tmpobjset->nodeTab[count2];
if (!tool.isElement(node)) continue;
result = checkFormat_list(node);
}
xmlXPathFreeObject(tmpobj);
}
}
xmlXPathFreeObject(children);
}
return result;
}
syntax highlighted by Code2HTML, v. 0.9.1