001/*
002 * (C) Copyright 2006-2018 Nuxeo (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     Florent Guillaume
018 */
019package org.nuxeo.ecm.core.storage;
020
021import java.util.ArrayList;
022import java.util.HashSet;
023import java.util.List;
024import java.util.Objects;
025import java.util.Set;
026
027import org.nuxeo.common.xmap.annotation.XNode;
028import org.nuxeo.common.xmap.annotation.XNodeList;
029import org.nuxeo.common.xmap.annotation.XObject;
030
031/**
032 * Structure holding fulltext descriptor info for generic fulltext indexing.
033 * <p>
034 * Not directly a XObject, but used by various RepositoryDescriptors.
035 *
036 * @since 7.10-HF04, 8.1
037 */
038public class FulltextDescriptor {
039
040    @XObject(value = "index")
041    public static class FulltextIndexDescriptor {
042
043        @XNode("@name")
044        public String name;
045
046        /** string or blob */
047        @XNode("fieldType")
048        public String fieldType;
049
050        @XNodeList(value = "field", type = HashSet.class, componentType = String.class)
051        public Set<String> fields = new HashSet<>(0);
052
053        @XNodeList(value = "excludeField", type = HashSet.class, componentType = String.class)
054        public Set<String> excludeFields = new HashSet<>(0);
055
056        public FulltextIndexDescriptor() {
057        }
058
059        /** Copy constructor. */
060        public FulltextIndexDescriptor(FulltextIndexDescriptor other) {
061            name = other.name;
062            fieldType = other.fieldType;
063            fields = new HashSet<>(other.fields);
064            excludeFields = new HashSet<>(other.excludeFields);
065        }
066
067        public static List<FulltextIndexDescriptor> copyList(List<FulltextIndexDescriptor> other) {
068            List<FulltextIndexDescriptor> copy = new ArrayList<>(other.size());
069            for (FulltextIndexDescriptor fid : other) {
070                copy.add(new FulltextIndexDescriptor(fid));
071            }
072            return copy;
073        }
074
075        public void merge(FulltextIndexDescriptor other) {
076            if (other.name != null) {
077                name = other.name;
078            }
079            if (other.fieldType != null) {
080                fieldType = other.fieldType;
081            }
082            fields.addAll(other.fields);
083            excludeFields.addAll(other.excludeFields);
084        }
085    }
086
087    public static final int FULLTEXT_FIELD_SIZE_LIMIT_DEFAULT = 128 * 1024; // 128 K
088
089    private Integer fulltextFieldSizeLimit;
090
091    public int getFulltextFieldSizeLimit() {
092        return fulltextFieldSizeLimit == null ? FULLTEXT_FIELD_SIZE_LIMIT_DEFAULT : fulltextFieldSizeLimit.intValue();
093    }
094
095    public void setFulltextFieldSizeLimit(int fulltextFieldSizeLimit) {
096        this.fulltextFieldSizeLimit = Integer.valueOf(fulltextFieldSizeLimit);
097    }
098
099    /** False if the boolean is null or FALSE, true otherwise. */
100    private static boolean defaultFalse(Boolean bool) {
101        return Boolean.TRUE.equals(bool);
102    }
103
104    private Boolean fulltextDisabled;
105
106    public boolean getFulltextDisabled() {
107        return defaultFalse(fulltextDisabled);
108    }
109
110    public void setFulltextDisabled(boolean disabled) {
111        fulltextDisabled = Boolean.valueOf(disabled);
112    }
113
114    private Boolean fulltextSearchDisabled;
115
116    public boolean getFulltextSearchDisabled() {
117        if (getFulltextDisabled()) {
118            return true;
119        }
120        return defaultFalse(fulltextSearchDisabled);
121    }
122
123    public void setFulltextSearchDisabled(boolean disabled) {
124        fulltextSearchDisabled = Boolean.valueOf(disabled);
125    }
126
127    private List<FulltextIndexDescriptor> fulltextIndexes = new ArrayList<>(0);
128
129    public List<FulltextIndexDescriptor> getFulltextIndexes() {
130        return fulltextIndexes;
131    }
132
133    public void setFulltextIndexes(List<FulltextIndexDescriptor> fulltextIndexes) {
134        this.fulltextIndexes = fulltextIndexes;
135    }
136
137    private Set<String> fulltextExcludedTypes = new HashSet<>(0);
138
139    public Set<String> getFulltextExcludedTypes() {
140        return fulltextExcludedTypes;
141    }
142
143    public void setFulltextExcludedTypes(Set<String> fulltextExcludedTypes) {
144        this.fulltextExcludedTypes = fulltextExcludedTypes;
145    }
146
147    private Set<String> fulltextIncludedTypes = new HashSet<>(0);
148
149    public Set<String> getFulltextIncludedTypes() {
150        return fulltextIncludedTypes;
151    }
152
153    public void setFulltextIncludedTypes(Set<String> fulltextIncludedTypes) {
154        this.fulltextIncludedTypes = fulltextIncludedTypes;
155    }
156
157    public FulltextDescriptor() {
158    }
159
160    /** Copy constructor. */
161    public FulltextDescriptor(FulltextDescriptor other) {
162        fulltextFieldSizeLimit = other.fulltextFieldSizeLimit;
163        fulltextDisabled = other.fulltextDisabled;
164        fulltextSearchDisabled = other.fulltextSearchDisabled;
165        fulltextIndexes = FulltextIndexDescriptor.copyList(other.fulltextIndexes);
166        fulltextExcludedTypes = new HashSet<>(other.fulltextExcludedTypes);
167        fulltextIncludedTypes = new HashSet<>(other.fulltextIncludedTypes);
168    }
169
170    public void merge(FulltextDescriptor other) {
171        if (other.fulltextFieldSizeLimit != null) {
172            fulltextFieldSizeLimit = other.fulltextFieldSizeLimit;
173        }
174        if (other.fulltextDisabled != null) {
175            fulltextDisabled = other.fulltextDisabled;
176        }
177        if (other.fulltextSearchDisabled != null) {
178            fulltextSearchDisabled = other.fulltextSearchDisabled;
179        }
180        for (FulltextIndexDescriptor oi : other.fulltextIndexes) {
181            boolean append = true;
182            for (FulltextIndexDescriptor i : fulltextIndexes) {
183                if (Objects.equals(i.name, oi.name)) {
184                    i.merge(oi);
185                    append = false;
186                    break;
187                }
188            }
189            if (append) {
190                fulltextIndexes.add(oi);
191            }
192        }
193        fulltextExcludedTypes.addAll(other.fulltextExcludedTypes);
194        fulltextIncludedTypes.addAll(other.fulltextIncludedTypes);
195    }
196
197}