Builders.h revision 6a008170cb18666e04c42856f992fc7a0afa1e1f
1/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef AAPT_TEST_BUILDERS_H
18#define AAPT_TEST_BUILDERS_H
19
20#include "ResourceTable.h"
21#include "ResourceValues.h"
22#include "test/Common.h"
23#include "util/Util.h"
24#include "xml/XmlDom.h"
25
26#include <memory>
27
28namespace aapt {
29namespace test {
30
31class ResourceTableBuilder {
32private:
33    DummyDiagnosticsImpl mDiagnostics;
34    std::unique_ptr<ResourceTable> mTable = util::make_unique<ResourceTable>();
35
36public:
37    ResourceTableBuilder() = default;
38
39    StringPool* getStringPool() {
40        return &mTable->stringPool;
41    }
42
43    ResourceTableBuilder& setPackageId(const StringPiece16& packageName, uint8_t id) {
44        ResourceTablePackage* package = mTable->createPackage(packageName, id);
45        assert(package);
46        return *this;
47    }
48
49    ResourceTableBuilder& addSimple(const StringPiece16& name, const ResourceId id = {}) {
50        return addValue(name, id, util::make_unique<Id>());
51    }
52
53    ResourceTableBuilder& addReference(const StringPiece16& name, const StringPiece16& ref) {
54        return addReference(name, {}, ref);
55    }
56
57    ResourceTableBuilder& addReference(const StringPiece16& name, const ResourceId id,
58                                       const StringPiece16& ref) {
59        return addValue(name, id, util::make_unique<Reference>(parseNameOrDie(ref)));
60    }
61
62    ResourceTableBuilder& addString(const StringPiece16& name, const StringPiece16& str) {
63        return addString(name, {}, str);
64    }
65
66    ResourceTableBuilder& addString(const StringPiece16& name, const ResourceId id,
67                                    const StringPiece16& str) {
68        return addValue(name, id, util::make_unique<String>(mTable->stringPool.makeRef(str)));
69    }
70
71    ResourceTableBuilder& addString(const StringPiece16& name, const ResourceId id,
72                                    const ConfigDescription& config, const StringPiece16& str) {
73        return addValue(name, id, config,
74                        util::make_unique<String>(mTable->stringPool.makeRef(str)));
75    }
76
77    ResourceTableBuilder& addFileReference(const StringPiece16& name, const StringPiece16& path) {
78        return addFileReference(name, {}, path);
79    }
80
81    ResourceTableBuilder& addFileReference(const StringPiece16& name, const ResourceId id,
82                                           const StringPiece16& path) {
83        return addValue(name, id,
84                        util::make_unique<FileReference>(mTable->stringPool.makeRef(path)));
85    }
86
87    ResourceTableBuilder& addFileReference(const StringPiece16& name, const StringPiece16& path,
88                                           const ConfigDescription& config) {
89        return addValue(name, {}, config,
90                        util::make_unique<FileReference>(mTable->stringPool.makeRef(path)));
91    }
92
93    ResourceTableBuilder& addValue(const StringPiece16& name,
94                                   std::unique_ptr<Value> value) {
95        return addValue(name, {}, std::move(value));
96    }
97
98    ResourceTableBuilder& addValue(const StringPiece16& name, const ResourceId id,
99                                       std::unique_ptr<Value> value) {
100        return addValue(name, id, {}, std::move(value));
101    }
102
103    ResourceTableBuilder& addValue(const StringPiece16& name, const ResourceId id,
104                                   const ConfigDescription& config,
105                                   std::unique_ptr<Value> value) {
106        ResourceName resName = parseNameOrDie(name);
107        bool result = mTable->addResourceAllowMangled(resName, id, config, std::move(value),
108                                                      &mDiagnostics);
109        assert(result);
110        return *this;
111    }
112
113    ResourceTableBuilder& setSymbolState(const StringPiece16& name, ResourceId id,
114                                         SymbolState state) {
115        ResourceName resName = parseNameOrDie(name);
116        Symbol symbol;
117        symbol.state = state;
118        bool result = mTable->setSymbolStateAllowMangled(resName, id, symbol, &mDiagnostics);
119        assert(result);
120        return *this;
121    }
122
123    std::unique_ptr<ResourceTable> build() {
124        return std::move(mTable);
125    }
126};
127
128inline std::unique_ptr<Reference> buildReference(const StringPiece16& ref,
129                                                 Maybe<ResourceId> id = {}) {
130    std::unique_ptr<Reference> reference = util::make_unique<Reference>(parseNameOrDie(ref));
131    reference->id = id;
132    return reference;
133}
134
135template <typename T>
136class ValueBuilder {
137private:
138    std::unique_ptr<Value> mValue;
139
140public:
141    template <typename... Args>
142    ValueBuilder(Args&&... args) : mValue(new T{ std::forward<Args>(args)... }) {
143    }
144
145    template <typename... Args>
146    ValueBuilder& setSource(Args&&... args) {
147        mValue->setSource(Source{ std::forward<Args>(args)... });
148        return *this;
149    }
150
151    ValueBuilder& setComment(const StringPiece16& str) {
152        mValue->setComment(str);
153        return *this;
154    }
155
156    std::unique_ptr<Value> build() {
157        return std::move(mValue);
158    }
159};
160
161class AttributeBuilder {
162private:
163    std::unique_ptr<Attribute> mAttr;
164
165public:
166    AttributeBuilder(bool weak = false) : mAttr(util::make_unique<Attribute>(weak)) {
167        mAttr->typeMask = android::ResTable_map::TYPE_ANY;
168    }
169
170    AttributeBuilder& setTypeMask(uint32_t typeMask) {
171        mAttr->typeMask = typeMask;
172        return *this;
173    }
174
175    AttributeBuilder& addItem(const StringPiece16& name, uint32_t value) {
176        mAttr->symbols.push_back(Attribute::Symbol{
177                Reference(ResourceName{ {}, ResourceType::kId, name.toString()}),
178                value});
179        return *this;
180    }
181
182    std::unique_ptr<Attribute> build() {
183        return std::move(mAttr);
184    }
185};
186
187class StyleBuilder {
188private:
189    std::unique_ptr<Style> mStyle = util::make_unique<Style>();
190
191public:
192    StyleBuilder& setParent(const StringPiece16& str) {
193        mStyle->parent = Reference(parseNameOrDie(str));
194        return *this;
195    }
196
197    StyleBuilder& addItem(const StringPiece16& str, std::unique_ptr<Item> value) {
198        mStyle->entries.push_back(Style::Entry{ Reference(parseNameOrDie(str)), std::move(value) });
199        return *this;
200    }
201
202    StyleBuilder& addItem(const StringPiece16& str, ResourceId id, std::unique_ptr<Item> value) {
203        addItem(str, std::move(value));
204        mStyle->entries.back().key.id = id;
205        return *this;
206    }
207
208    std::unique_ptr<Style> build() {
209        return std::move(mStyle);
210    }
211};
212
213class StyleableBuilder {
214private:
215    std::unique_ptr<Styleable> mStyleable = util::make_unique<Styleable>();
216
217public:
218    StyleableBuilder& addItem(const StringPiece16& str, Maybe<ResourceId> id = {}) {
219        mStyleable->entries.push_back(Reference(parseNameOrDie(str)));
220        mStyleable->entries.back().id = id;
221        return *this;
222    }
223
224    std::unique_ptr<Styleable> build() {
225        return std::move(mStyleable);
226    }
227};
228
229inline std::unique_ptr<xml::XmlResource> buildXmlDom(const StringPiece& str) {
230    std::stringstream in;
231    in << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" << str;
232    StdErrDiagnostics diag;
233    std::unique_ptr<xml::XmlResource> doc = xml::inflate(&in, &diag, {});
234    assert(doc);
235    return doc;
236}
237
238inline std::unique_ptr<xml::XmlResource> buildXmlDomForPackageName(IAaptContext* context,
239                                                                   const StringPiece& str) {
240    std::unique_ptr<xml::XmlResource> doc = buildXmlDom(str);
241    doc->file.name.package = context->getCompilationPackage().toString();
242    return doc;
243}
244
245} // namespace test
246} // namespace aapt
247
248#endif /* AAPT_TEST_BUILDERS_H */
249