Builders.h revision e78fd617ec60139a973a01925fa7adad31febb39
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 "util/Util.h"
23#include "XmlDom.h"
24
25#include "test/Common.h"
26
27#include <memory>
28
29namespace aapt {
30namespace test {
31
32class ResourceTableBuilder {
33private:
34    DummyDiagnosticsImpl mDiagnostics;
35    std::unique_ptr<ResourceTable> mTable = util::make_unique<ResourceTable>();
36
37public:
38    ResourceTableBuilder() = default;
39
40    ResourceTableBuilder& setPackageId(const StringPiece16& packageName, uint8_t id) {
41        ResourceTablePackage* package = mTable->createPackage(packageName, id);
42        assert(package);
43        return *this;
44    }
45
46    ResourceTableBuilder& addSimple(const StringPiece16& name, const ResourceId id = {}) {
47        return addValue(name, id, util::make_unique<Id>());
48    }
49
50    ResourceTableBuilder& addReference(const StringPiece16& name, const StringPiece16& ref) {
51        return addReference(name, {}, ref);
52    }
53
54    ResourceTableBuilder& addReference(const StringPiece16& name, const ResourceId id,
55                                       const StringPiece16& ref) {
56        return addValue(name, id, util::make_unique<Reference>(parseNameOrDie(ref)));
57    }
58
59    ResourceTableBuilder& addString(const StringPiece16& name, const StringPiece16& str) {
60        return addString(name, {}, str);
61    }
62
63    ResourceTableBuilder& addString(const StringPiece16& name, const ResourceId id,
64                                    const StringPiece16& str) {
65        return addValue(name, id, util::make_unique<String>(mTable->stringPool.makeRef(str)));
66    }
67
68    ResourceTableBuilder& addFileReference(const StringPiece16& name, const StringPiece16& path) {
69        return addFileReference(name, {}, path);
70    }
71
72    ResourceTableBuilder& addFileReference(const StringPiece16& name, const ResourceId id,
73                                           const StringPiece16& path) {
74        return addValue(name, id,
75                        util::make_unique<FileReference>(mTable->stringPool.makeRef(path)));
76    }
77
78
79    ResourceTableBuilder& addValue(const StringPiece16& name,
80                                   std::unique_ptr<Value> value) {
81        return addValue(name, {}, std::move(value));
82    }
83
84    ResourceTableBuilder& addValue(const StringPiece16& name, const ResourceId id,
85                                       std::unique_ptr<Value> value) {
86        return addValue(name, id, {}, std::move(value));
87    }
88
89    ResourceTableBuilder& addValue(const StringPiece16& name, const ResourceId id,
90                                   const ConfigDescription& config,
91                                   std::unique_ptr<Value> value) {
92        ResourceName resName = parseNameOrDie(name);
93        bool result = mTable->addResourceAllowMangled(resName, id, config, std::move(value),
94                                                      &mDiagnostics);
95        assert(result);
96        return *this;
97    }
98
99    ResourceTableBuilder& setSymbolState(const StringPiece16& name, ResourceId id,
100                                         SymbolState state) {
101        ResourceName resName = parseNameOrDie(name);
102        Symbol symbol;
103        symbol.state = state;
104        bool result = mTable->setSymbolStateAllowMangled(resName, id, symbol, &mDiagnostics);
105        assert(result);
106        return *this;
107    }
108
109    std::unique_ptr<ResourceTable> build() {
110        return std::move(mTable);
111    }
112};
113
114inline std::unique_ptr<Reference> buildReference(const StringPiece16& ref,
115                                                 Maybe<ResourceId> id = {}) {
116    std::unique_ptr<Reference> reference = util::make_unique<Reference>(parseNameOrDie(ref));
117    reference->id = id;
118    return reference;
119}
120
121template <typename T>
122class ValueBuilder {
123private:
124    std::unique_ptr<Value> mValue;
125
126public:
127    template <typename... Args>
128    ValueBuilder(Args&&... args) : mValue(new T{ std::forward<Args>(args)... }) {
129    }
130
131    template <typename... Args>
132    ValueBuilder& setSource(Args&&... args) {
133        mValue->setSource(Source{ std::forward<Args>(args)... });
134        return *this;
135    }
136
137    ValueBuilder& setComment(const StringPiece16& str) {
138        mValue->setComment(str);
139        return *this;
140    }
141
142    std::unique_ptr<Value> build() {
143        return std::move(mValue);
144    }
145};
146
147class AttributeBuilder {
148private:
149    std::unique_ptr<Attribute> mAttr;
150
151public:
152    AttributeBuilder(bool weak = false) : mAttr(util::make_unique<Attribute>(weak)) {
153        mAttr->typeMask = android::ResTable_map::TYPE_ANY;
154    }
155
156    AttributeBuilder& setTypeMask(uint32_t typeMask) {
157        mAttr->typeMask = typeMask;
158        return *this;
159    }
160
161    AttributeBuilder& addItem(const StringPiece16& name, uint32_t value) {
162        mAttr->symbols.push_back(Attribute::Symbol{
163                Reference(ResourceName{ {}, ResourceType::kId, name.toString()}),
164                value});
165        return *this;
166    }
167
168    std::unique_ptr<Attribute> build() {
169        return std::move(mAttr);
170    }
171};
172
173class StyleBuilder {
174private:
175    std::unique_ptr<Style> mStyle = util::make_unique<Style>();
176
177public:
178    StyleBuilder& setParent(const StringPiece16& str) {
179        mStyle->parent = Reference(parseNameOrDie(str));
180        return *this;
181    }
182
183    StyleBuilder& addItem(const StringPiece16& str, std::unique_ptr<Item> value) {
184        mStyle->entries.push_back(Style::Entry{ Reference(parseNameOrDie(str)), std::move(value) });
185        return *this;
186    }
187
188    StyleBuilder& addItem(const StringPiece16& str, ResourceId id, std::unique_ptr<Item> value) {
189        addItem(str, std::move(value));
190        mStyle->entries.back().key.id = id;
191        return *this;
192    }
193
194    std::unique_ptr<Style> build() {
195        return std::move(mStyle);
196    }
197};
198
199class StyleableBuilder {
200private:
201    std::unique_ptr<Styleable> mStyleable = util::make_unique<Styleable>();
202
203public:
204    StyleableBuilder& addItem(const StringPiece16& str, Maybe<ResourceId> id = {}) {
205        mStyleable->entries.push_back(Reference(parseNameOrDie(str)));
206        mStyleable->entries.back().id = id;
207        return *this;
208    }
209
210    std::unique_ptr<Styleable> build() {
211        return std::move(mStyleable);
212    }
213};
214
215inline std::unique_ptr<XmlResource> buildXmlDom(const StringPiece& str) {
216    std::stringstream in;
217    in << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" << str;
218    StdErrDiagnostics diag;
219    std::unique_ptr<XmlResource> doc = xml::inflate(&in, &diag, {});
220    assert(doc);
221    return doc;
222}
223
224} // namespace test
225} // namespace aapt
226
227#endif /* AAPT_TEST_BUILDERS_H */
228