1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 #include "precompiled_configmgr.hxx" 25 #include "sal/config.h" 26 27 #include <climits> 28 29 #include "com/sun/star/uno/Reference.hxx" 30 #include "com/sun/star/uno/RuntimeException.hpp" 31 #include "com/sun/star/uno/XInterface.hpp" 32 #include "osl/diagnose.hxx" 33 #include "rtl/string.h" 34 #include "rtl/ustring.h" 35 #include "rtl/ustring.hxx" 36 #include "xmlreader/span.hxx" 37 #include "xmlreader/xmlreader.hxx" 38 39 #include "parsemanager.hxx" 40 #include "xcdparser.hxx" 41 #include "xcsparser.hxx" 42 #include "xcuparser.hxx" 43 #include "xmldata.hxx" 44 45 namespace configmgr { 46 47 namespace { 48 49 namespace css = com::sun::star; 50 51 } 52 53 XcdParser::XcdParser(int layer, Dependencies const & dependencies, Data & data): 54 layer_(layer), dependencies_(dependencies), data_(data), state_(STATE_START) 55 {} 56 57 XcdParser::~XcdParser() {} 58 59 xmlreader::XmlReader::Text XcdParser::getTextMode() { 60 return nestedParser_.is() 61 ? nestedParser_->getTextMode() : xmlreader::XmlReader::TEXT_NONE; 62 } 63 64 bool XcdParser::startElement( 65 xmlreader::XmlReader & reader, int nsId, xmlreader::Span const & name) 66 { 67 if (nestedParser_.is()) { 68 OSL_ASSERT(nesting_ != LONG_MAX); 69 ++nesting_; 70 return nestedParser_->startElement(reader, nsId, name); 71 } 72 switch (state_) { 73 case STATE_START: 74 if (nsId == ParseManager::NAMESPACE_OOR && 75 name.equals(RTL_CONSTASCII_STRINGPARAM("data"))) 76 { 77 state_ = STATE_DEPENDENCIES; 78 return true; 79 } 80 break; 81 case STATE_DEPENDENCIES: 82 if (nsId == xmlreader::XmlReader::NAMESPACE_NONE && 83 name.equals(RTL_CONSTASCII_STRINGPARAM("dependency"))) 84 { 85 if (dependency_.getLength() == 0) { 86 xmlreader::Span attrFile; 87 for (;;) { 88 int attrNsId; 89 xmlreader::Span attrLn; 90 if (!reader.nextAttribute(&attrNsId, &attrLn)) { 91 break; 92 } 93 if (attrNsId == xmlreader::XmlReader::NAMESPACE_NONE && 94 //TODO: _OOR 95 attrLn.equals(RTL_CONSTASCII_STRINGPARAM("file"))) 96 { 97 attrFile = reader.getAttributeValue(false); 98 } 99 } 100 if (!attrFile.is()) { 101 throw css::uno::RuntimeException( 102 (rtl::OUString( 103 RTL_CONSTASCII_USTRINGPARAM( 104 "no dependency file attribute in ")) + 105 reader.getUrl()), 106 css::uno::Reference< css::uno::XInterface >()); 107 } 108 dependency_ = attrFile.convertFromUtf8(); 109 if (dependency_.getLength() == 0) { 110 throw css::uno::RuntimeException( 111 (rtl::OUString( 112 RTL_CONSTASCII_USTRINGPARAM( 113 "bad dependency file attribute in ")) + 114 reader.getUrl()), 115 css::uno::Reference< css::uno::XInterface >()); 116 } 117 } 118 if (dependencies_.find(dependency_) == dependencies_.end()) { 119 return false; 120 } 121 state_ = STATE_DEPENDENCY; 122 dependency_ = rtl::OUString(); 123 return true; 124 } 125 state_ = STATE_COMPONENTS; 126 // fall through 127 case STATE_COMPONENTS: 128 if (nsId == ParseManager::NAMESPACE_OOR && 129 name.equals(RTL_CONSTASCII_STRINGPARAM("component-schema"))) 130 { 131 nestedParser_ = new XcsParser(layer_, data_); 132 nesting_ = 1; 133 return nestedParser_->startElement(reader, nsId, name); 134 } 135 if (nsId == ParseManager::NAMESPACE_OOR && 136 name.equals(RTL_CONSTASCII_STRINGPARAM("component-data"))) 137 { 138 nestedParser_ = new XcuParser(layer_ + 1, data_, 0, 0, 0); 139 nesting_ = 1; 140 return nestedParser_->startElement(reader, nsId, name); 141 } 142 break; 143 default: // STATE_DEPENDENCY 144 OSL_ASSERT(false); // this cannot happen 145 break; 146 } 147 throw css::uno::RuntimeException( 148 (rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("bad member <")) + 149 name.convertFromUtf8() + 150 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("> in ")) + reader.getUrl()), 151 css::uno::Reference< css::uno::XInterface >()); 152 } 153 154 void XcdParser::endElement(xmlreader::XmlReader const & reader) { 155 if (nestedParser_.is()) { 156 nestedParser_->endElement(reader); 157 if (--nesting_ == 0) { 158 nestedParser_.clear(); 159 } 160 } else { 161 switch (state_) { 162 case STATE_DEPENDENCY: 163 state_ = STATE_DEPENDENCIES; 164 break; 165 case STATE_DEPENDENCIES: 166 case STATE_COMPONENTS: 167 break; 168 default: 169 OSL_ASSERT(false); // this cannot happen 170 break; 171 } 172 } 173 } 174 175 void XcdParser::characters(xmlreader::Span const & text) { 176 if (nestedParser_.is()) { 177 nestedParser_->characters(text); 178 } 179 } 180 181 } 182