Home | History | Annotate | Download | only in java
      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 
     39     AnnotationProcessor* getCommentBuilder() {
     40         return &mProcessor;
     41     }
     42 
     43     virtual bool empty() const = 0;
     44 
     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:
     56     PrimitiveMember(const StringPiece& name, const T& val) :
     57             mName(name.toString()), mVal(val) {
     58     }
     59 
     60     bool empty() const override {
     61         return false;
     62     }
     63 
     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:
     84     PrimitiveMember(const StringPiece& name, const std::string& val) :
     85             mName(name.toString()), mVal(val) {
     86     }
     87 
     88     bool empty() const override {
     89         return false;
     90     }
     91 
     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:
    113     PrimitiveArrayMember(const StringPiece& name) :
    114             mName(name.toString()) {
    115     }
    116 
    117     void addElement(const T& val) {
    118         mElements.push_back(val);
    119     }
    120 
    121     bool empty() const override {
    122         return false;
    123     }
    124 
    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 
    166     ClassDefinition(const StringPiece& name, ClassQualifier qualifier, bool createIfEmpty) :
    167             mName(name.toString()), mQualifier(qualifier), mCreateIfEmpty(createIfEmpty) {
    168     }
    169 
    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