Kaydet (Commit) 05310858 authored tarafından Stephan Bergmann's avatar Stephan Bergmann

Support optional dependencies among .xcd files

...that are effectively ignored if the depended-on file does not exist.  This
will be needed by a subsequent commit to make PDF Import optionally installable.

Change-Id: I2283be3ce75f52811a371f41aa8784f507425ee3
üst 6042f861
......@@ -23,6 +23,7 @@
#include <cassert>
#include <cstddef>
#include <list>
#include <set>
#include "com/sun/star/beans/Optional.hpp"
#include "com/sun/star/beans/UnknownPropertyException.hpp"
......@@ -92,7 +93,7 @@ void parseXcsFile(
assert(partial == 0 && modifications == 0 && additions == 0);
(void) partial; (void) modifications; (void) additions;
bool ok = rtl::Reference< ParseManager >(
new ParseManager(url, new XcsParser(layer, data)))->parse();
new ParseManager(url, new XcsParser(layer, data)))->parse(0);
assert(ok);
(void) ok; // avoid warnings
}
......@@ -107,7 +108,7 @@ void parseXcuFile(
new ParseManager(
url,
new XcuParser(layer, data, partial, modifications, additions)))->
parse();
parse(0);
assert(ok);
(void) ok; // avoid warnings
}
......@@ -724,7 +725,8 @@ void Components::parseXcdFiles(int layer, rtl::OUString const & url) {
css::uno::Reference< css::uno::XInterface >());
}
UnresolvedList unres;
XcdParser::Dependencies deps;
std::set< OUString > existingDeps;
std::set< OUString > processedDeps;
for (;;) {
osl::DirectoryItem i;
osl::FileBase::RC rc = dir.getNextItem(i, SAL_MAX_UINT32);
......@@ -758,10 +760,12 @@ void Components::parseXcdFiles(int layer, rtl::OUString const & url) {
rtl::OUString name(
file.copy(
0, file.getLength() - RTL_CONSTASCII_LENGTH(".xcd")));
existingDeps.insert(name);
rtl::Reference< ParseManager > manager;
try {
manager = new ParseManager(
stat.getFileURL(), new XcdParser(layer, deps, data_));
stat.getFileURL(),
new XcdParser(layer, processedDeps, data_));
} catch (css::container::NoSuchElementException & e) {
throw css::uno::RuntimeException(
(rtl::OUString(
......@@ -770,8 +774,8 @@ void Components::parseXcdFiles(int layer, rtl::OUString const & url) {
e.Message),
css::uno::Reference< css::uno::XInterface >());
}
if (manager->parse()) {
deps.insert(name);
if (manager->parse(0)) {
processedDeps.insert(name);
} else {
unres.push_back(UnresolvedListItem(name, manager));
}
......@@ -781,8 +785,8 @@ void Components::parseXcdFiles(int layer, rtl::OUString const & url) {
while (!unres.empty()) {
bool resolved = false;
for (UnresolvedList::iterator i(unres.begin()); i != unres.end();) {
if (i->manager->parse()) {
deps.insert(i->name);
if (i->manager->parse(&existingDeps)) {
processedDeps.insert(i->name);
unres.erase(i++);
resolved = true;
} else {
......
......@@ -20,6 +20,7 @@
#include "sal/config.h"
#include <cassert>
#include <set>
#include "com/sun/star/container/NoSuchElementException.hpp"
#include "com/sun/star/uno/RuntimeException.hpp"
......@@ -62,7 +63,7 @@ ParseManager::ParseManager(
(void)id;
}
bool ParseManager::parse() {
bool ParseManager::parse(std::set< OUString > const * existingDependencies) {
for (;;) {
switch (itemData_.is()
? xmlreader::XmlReader::RESULT_BEGIN
......@@ -70,7 +71,8 @@ bool ParseManager::parse() {
parser_->getTextMode(), &itemData_, &itemNamespaceId_))
{
case xmlreader::XmlReader::RESULT_BEGIN:
if (!parser_->startElement(reader_, itemNamespaceId_, itemData_))
if (!parser_->startElement(
reader_, itemNamespaceId_, itemData_, existingDependencies))
{
return false;
}
......
......@@ -22,6 +22,8 @@
#include "sal/config.h"
#include <set>
#include "com/sun/star/container/NoSuchElementException.hpp"
#include "com/sun/star/uno/RuntimeException.hpp"
#include "rtl/ref.hxx"
......@@ -44,7 +46,7 @@ public:
com::sun::star::container::NoSuchElementException,
com::sun::star::uno::RuntimeException));
bool parse();
bool parse(std::set< rtl::OUString > const * existingDependencies);
enum { NAMESPACE_OOR = 1, NAMESPACE_XS = 2, NAMESPACE_XSI = 3 };
......
......@@ -23,10 +23,12 @@
#include "sal/config.h"
#include <memory>
#include <set>
#include "salhelper/simplereferenceobject.hxx"
#include "xmlreader/xmlreader.hxx"
namespace rtl { class OUString; }
namespace xmlreader { struct Span; }
namespace configmgr {
......@@ -36,8 +38,8 @@ public:
virtual xmlreader::XmlReader::Text getTextMode() = 0;
virtual bool startElement(
xmlreader::XmlReader & reader, int nsId, xmlreader::Span const & name)
= 0;
xmlreader::XmlReader & reader, int nsId, xmlreader::Span const & name,
std::set< rtl::OUString > const * existingDependencies) = 0;
virtual void endElement(xmlreader::XmlReader const & reader) = 0;
......
......@@ -20,6 +20,7 @@
#include "sal/config.h"
#include <cassert>
#include <set>
#include "com/sun/star/uno/Any.hxx"
#include "com/sun/star/uno/Reference.hxx"
......@@ -287,7 +288,8 @@ xmlreader::XmlReader::Text ValueParser::getTextMode() const {
}
bool ValueParser::startElement(
xmlreader::XmlReader & reader, int nsId, xmlreader::Span const & name)
xmlreader::XmlReader & reader, int nsId, xmlreader::Span const & name,
std::set< rtl::OUString > const *)
{
if (!node_.is()) {
return false;
......
......@@ -22,6 +22,7 @@
#include "sal/config.h"
#include <set>
#include <vector>
#include "boost/noncopyable.hpp"
......@@ -51,7 +52,8 @@ public:
xmlreader::XmlReader::Text getTextMode() const;
bool startElement(
xmlreader::XmlReader & reader, int nsId, xmlreader::Span const & name);
xmlreader::XmlReader & reader, int nsId, xmlreader::Span const & name,
std::set< OUString > const *);
bool endElement();
......
......@@ -21,6 +21,7 @@
#include <cassert>
#include <climits>
#include <set>
#include "com/sun/star/uno/Reference.hxx"
#include "com/sun/star/uno/RuntimeException.hpp"
......@@ -45,8 +46,10 @@ namespace css = com::sun::star;
}
XcdParser::XcdParser(int layer, Dependencies const & dependencies, Data & data):
layer_(layer), dependencies_(dependencies), data_(data), state_(STATE_START)
XcdParser::XcdParser(
int layer, std::set< OUString > const & processedDependencies, Data & data):
layer_(layer), processedDependencies_(processedDependencies), data_(data),
state_(STATE_START)
{}
XcdParser::~XcdParser() {}
......@@ -57,12 +60,14 @@ xmlreader::XmlReader::Text XcdParser::getTextMode() {
}
bool XcdParser::startElement(
xmlreader::XmlReader & reader, int nsId, xmlreader::Span const & name)
xmlreader::XmlReader & reader, int nsId, xmlreader::Span const & name,
std::set< OUString > const * existingDependencies)
{
if (nestedParser_.is()) {
assert(nesting_ != LONG_MAX);
++nesting_;
return nestedParser_->startElement(reader, nsId, name);
return nestedParser_->startElement(
reader, nsId, name, existingDependencies);
}
switch (state_) {
case STATE_START:
......@@ -77,7 +82,8 @@ bool XcdParser::startElement(
if (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
name.equals(RTL_CONSTASCII_STRINGPARAM("dependency")))
{
if (dependency_.isEmpty()) {
if (dependencyFile_.isEmpty()) {
dependencyOptional_ = false;
xmlreader::Span attrFile;
for (;;) {
int attrNsId;
......@@ -90,6 +96,13 @@ bool XcdParser::startElement(
attrLn.equals(RTL_CONSTASCII_STRINGPARAM("file")))
{
attrFile = reader.getAttributeValue(false);
} else if ((attrNsId ==
xmlreader::XmlReader::NAMESPACE_NONE) &&
attrLn.equals(
RTL_CONSTASCII_STRINGPARAM("optional")))
{
dependencyOptional_ = xmldata::parseBoolean(
reader.getAttributeValue(true));
}
}
if (!attrFile.is()) {
......@@ -100,8 +113,8 @@ bool XcdParser::startElement(
reader.getUrl()),
css::uno::Reference< css::uno::XInterface >());
}
dependency_ = attrFile.convertFromUtf8();
if (dependency_.isEmpty()) {
dependencyFile_ = attrFile.convertFromUtf8();
if (dependencyFile_.isEmpty()) {
throw css::uno::RuntimeException(
(rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM(
......@@ -110,11 +123,16 @@ bool XcdParser::startElement(
css::uno::Reference< css::uno::XInterface >());
}
}
if (dependencies_.find(dependency_) == dependencies_.end()) {
if ((processedDependencies_.find(dependencyFile_) ==
processedDependencies_.end()) &&
(!dependencyOptional_ || existingDependencies == 0 ||
(existingDependencies->find(dependencyFile_) !=
existingDependencies->end())))
{
return false;
}
state_ = STATE_DEPENDENCY;
dependency_ = rtl::OUString();
dependencyFile_ = rtl::OUString();
return true;
}
state_ = STATE_COMPONENTS;
......@@ -125,14 +143,16 @@ bool XcdParser::startElement(
{
nestedParser_ = new XcsParser(layer_, data_);
nesting_ = 1;
return nestedParser_->startElement(reader, nsId, name);
return nestedParser_->startElement(
reader, nsId, name, existingDependencies);
}
if (nsId == ParseManager::NAMESPACE_OOR &&
name.equals(RTL_CONSTASCII_STRINGPARAM("component-data")))
{
nestedParser_ = new XcuParser(layer_ + 1, data_, 0, 0, 0);
nesting_ = 1;
return nestedParser_->startElement(reader, nsId, name);
return nestedParser_->startElement(
reader, nsId, name, existingDependencies);
}
break;
default: // STATE_DEPENDENCY
......
......@@ -38,9 +38,9 @@ struct Data;
class XcdParser: public Parser {
public:
typedef std::set< rtl::OUString > Dependencies;
XcdParser(int layer, Dependencies const & dependencies, Data & data);
XcdParser(
int layer, std::set< OUString > const & processedDependencies,
Data & data);
private:
virtual ~XcdParser();
......@@ -48,7 +48,8 @@ private:
virtual xmlreader::XmlReader::Text getTextMode();
virtual bool startElement(
xmlreader::XmlReader & reader, int nsId, xmlreader::Span const & name);
xmlreader::XmlReader & reader, int nsId, xmlreader::Span const & name,
std::set< OUString > const * existingDependencies);
virtual void endElement(xmlreader::XmlReader const & reader);
......@@ -58,10 +59,11 @@ private:
STATE_START, STATE_DEPENDENCIES, STATE_DEPENDENCY, STATE_COMPONENTS };
int layer_;
Dependencies const & dependencies_;
std::set< OUString > const & processedDependencies_;
Data & data_;
State state_;
rtl::OUString dependency_;
rtl::OUString dependencyFile_;
bool dependencyOptional_;
rtl::Reference< Parser > nestedParser_;
long nesting_;
};
......
......@@ -21,6 +21,7 @@
#include <cassert>
#include <cstddef>
#include <set>
#include "com/sun/star/uno/Any.hxx"
#include "com/sun/star/uno/Reference.hxx"
......@@ -127,9 +128,10 @@ xmlreader::XmlReader::Text XcsParser::getTextMode() {
}
bool XcsParser::startElement(
xmlreader::XmlReader & reader, int nsId, xmlreader::Span const & name)
xmlreader::XmlReader & reader, int nsId, xmlreader::Span const & name,
std::set< OUString > const * existingDependencies)
{
if (valueParser_.startElement(reader, nsId, name)) {
if (valueParser_.startElement(reader, nsId, name, existingDependencies)) {
return true;
}
if (state_ == STATE_START) {
......
......@@ -22,6 +22,7 @@
#include "sal/config.h"
#include <set>
#include <stack>
#include "rtl/ref.hxx"
......@@ -49,7 +50,8 @@ private:
virtual xmlreader::XmlReader::Text getTextMode();
virtual bool startElement(
xmlreader::XmlReader & reader, int nsId, xmlreader::Span const & name);
xmlreader::XmlReader & reader, int nsId, xmlreader::Span const & name,
std::set< rtl::OUString > const * existingDependencies);
virtual void endElement(xmlreader::XmlReader const & reader);
......
......@@ -21,6 +21,7 @@
#include <algorithm>
#include <cassert>
#include <set>
#include "com/sun/star/uno/Any.hxx"
#include "com/sun/star/uno/Reference.hxx"
......@@ -77,9 +78,10 @@ xmlreader::XmlReader::Text XcuParser::getTextMode() {
}
bool XcuParser::startElement(
xmlreader::XmlReader & reader, int nsId, xmlreader::Span const & name)
xmlreader::XmlReader & reader, int nsId, xmlreader::Span const & name,
std::set< OUString > const * existingDependencies)
{
if (valueParser_.startElement(reader, nsId, name)) {
if (valueParser_.startElement(reader, nsId, name, existingDependencies)) {
return true;
}
if (state_.empty()) {
......
......@@ -22,6 +22,7 @@
#include "sal/config.h"
#include <set>
#include <stack>
#include "rtl/ref.hxx"
......@@ -61,7 +62,8 @@ private:
virtual xmlreader::XmlReader::Text getTextMode();
virtual bool startElement(
xmlreader::XmlReader & reader, int nsId, xmlreader::Span const & name);
xmlreader::XmlReader & reader, int nsId, xmlreader::Span const & name,
std::set< OUString > const * existingDependencies);
virtual void endElement(xmlreader::XmlReader const & reader);
......
......@@ -22,7 +22,8 @@
<!ELEMENT dependency EMPTY>
<!ATTLIST dependency
file CDATA #REQUIRED>
file CDATA #REQUIRED
optional (false | true) #IMPLIED>
<!ENTITY % component-schema.dtd SYSTEM "component-schema.dtd">
%component-schema.dtd;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment