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