• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_JAVA_CLASSDEFINITION_H
18 #define AAPT_JAVA_CLASSDEFINITION_H
19 
20 #include "Resource.h"
21 #include "java/AnnotationProcessor.h"
22 #include "util/StringPiece.h"
23 #include "util/Util.h"
24 
25 #include <android-base/macros.h>
26 #include <sstream>
27 #include <string>
28 
29 namespace aapt {
30 
31 // The number of attributes to emit per line in a Styleable array.
32 constexpr static size_t kAttribsPerLine = 4;
33 constexpr static const char* kIndent = "  ";
34 
35 class ClassMember {
36 public:
37     virtual ~ClassMember() = default;
38 
getCommentBuilder()39     AnnotationProcessor* getCommentBuilder() {
40         return &mProcessor;
41     }
42 
43     virtual bool empty() const = 0;
44 
writeToStream(const StringPiece & prefix,bool final,std::ostream * out)45     virtual void writeToStream(const StringPiece& prefix, bool final, std::ostream* out) const {
46         mProcessor.writeToStream(out, prefix);
47     }
48 
49 private:
50     AnnotationProcessor mProcessor;
51 };
52 
53 template <typename T>
54 class PrimitiveMember : public ClassMember {
55 public:
PrimitiveMember(const StringPiece & name,const T & val)56     PrimitiveMember(const StringPiece& name, const T& val) :
57             mName(name.toString()), mVal(val) {
58     }
59 
empty()60     bool empty() const override {
61         return false;
62     }
63 
writeToStream(const StringPiece & prefix,bool final,std::ostream * out)64     void writeToStream(const StringPiece& prefix, bool final, std::ostream* out) const override {
65         ClassMember::writeToStream(prefix, final, out);
66 
67         *out << prefix << "public static " << (final ? "final " : "")
68              << "int " << mName << "=" << mVal << ";";
69     }
70 
71 private:
72     std::string mName;
73     T mVal;
74 
75     DISALLOW_COPY_AND_ASSIGN(PrimitiveMember);
76 };
77 
78 /**
79  * Specialization for strings so they get the right type and are quoted with "".
80  */
81 template <>
82 class PrimitiveMember<std::string> : public ClassMember {
83 public:
PrimitiveMember(const StringPiece & name,const std::string & val)84     PrimitiveMember(const StringPiece& name, const std::string& val) :
85             mName(name.toString()), mVal(val) {
86     }
87 
empty()88     bool empty() const override {
89         return false;
90     }
91 
writeToStream(const StringPiece & prefix,bool final,std::ostream * out)92     void writeToStream(const StringPiece& prefix, bool final, std::ostream* out) const override {
93         ClassMember::writeToStream(prefix, final, out);
94 
95         *out << prefix << "public static " << (final ? "final " : "")
96              << "String " << mName << "=\"" << mVal << "\";";
97     }
98 
99 private:
100     std::string mName;
101     std::string mVal;
102 
103     DISALLOW_COPY_AND_ASSIGN(PrimitiveMember);
104 };
105 
106 using IntMember = PrimitiveMember<uint32_t>;
107 using ResourceMember = PrimitiveMember<ResourceId>;
108 using StringMember = PrimitiveMember<std::string>;
109 
110 template <typename T>
111 class PrimitiveArrayMember : public ClassMember {
112 public:
PrimitiveArrayMember(const StringPiece & name)113     PrimitiveArrayMember(const StringPiece& name) :
114             mName(name.toString()) {
115     }
116 
addElement(const T & val)117     void addElement(const T& val) {
118         mElements.push_back(val);
119     }
120 
empty()121     bool empty() const override {
122         return false;
123     }
124 
writeToStream(const StringPiece & prefix,bool final,std::ostream * out)125     void writeToStream(const StringPiece& prefix, bool final, std::ostream* out) const override {
126         ClassMember::writeToStream(prefix, final, out);
127 
128         *out << prefix << "public static final int[] " << mName << "={";
129 
130         const auto begin = mElements.begin();
131         const auto end = mElements.end();
132         for (auto current = begin; current != end; ++current) {
133             if (std::distance(begin, current) % kAttribsPerLine == 0) {
134                 *out << "\n" << prefix << kIndent << kIndent;
135             }
136 
137             *out << *current;
138             if (std::distance(current, end) > 1) {
139                 *out << ", ";
140             }
141         }
142         *out << "\n" << prefix << kIndent <<"};";
143     }
144 
145 private:
146     std::string mName;
147     std::vector<T> mElements;
148 
149     DISALLOW_COPY_AND_ASSIGN(PrimitiveArrayMember);
150 };
151 
152 using ResourceArrayMember = PrimitiveArrayMember<ResourceId>;
153 
154 enum class ClassQualifier {
155     None,
156     Static
157 };
158 
159 class ClassDefinition : public ClassMember {
160 public:
161     static bool writeJavaFile(const ClassDefinition* def,
162                               const StringPiece& package,
163                               bool final,
164                               std::ostream* out);
165 
ClassDefinition(const StringPiece & name,ClassQualifier qualifier,bool createIfEmpty)166     ClassDefinition(const StringPiece& name, ClassQualifier qualifier, bool createIfEmpty) :
167             mName(name.toString()), mQualifier(qualifier), mCreateIfEmpty(createIfEmpty) {
168     }
169 
addMember(std::unique_ptr<ClassMember> member)170     void addMember(std::unique_ptr<ClassMember> member) {
171         mMembers.push_back(std::move(member));
172     }
173 
174     bool empty() const override;
175     void writeToStream(const StringPiece& prefix, bool final, std::ostream* out) const override;
176 
177 private:
178     std::string mName;
179     ClassQualifier mQualifier;
180     bool mCreateIfEmpty;
181     std::vector<std::unique_ptr<ClassMember>> mMembers;
182 
183     DISALLOW_COPY_AND_ASSIGN(ClassDefinition);
184 };
185 
186 } // namespace aapt
187 
188 #endif /* AAPT_JAVA_CLASSDEFINITION_H */
189