Project

General

Profile

1
/**
2
 * This work was created by participants in the DataONE project, and is
3
 * jointly copyrighted by participating institutions in DataONE. For 
4
 * more information on DataONE, see our web site at http://dataone.org.
5
 *
6
 *   Copyright ${year}
7
 *
8
 * Licensed under the Apache License, Version 2.0 (the "License");
9
 * you may not use this file except in compliance with the License.
10
 * You may obtain a copy of the License at
11
 *
12
 *   http://www.apache.org/licenses/LICENSE-2.0
13
 *
14
 * Unless required by applicable law or agreed to in writing, software
15
 * distributed under the License is distributed on an "AS IS" BASIS,
16
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
 * See the License for the specific language governing permissions and 
18
 * limitations under the License.
19
 * 
20
 * $Id: MetacatDocumentDeleteSubprocessor.java 9060 2015-01-07 20:02:25Z leinfelder $
21
 */
22

    
23
package edu.ucsb.nceas.metacat.index;
24
import java.io.IOException;
25
import java.util.ArrayList;
26
import java.util.HashSet;
27
import java.util.List;
28
import java.util.Map;
29
import java.util.Set;
30

    
31
import javax.xml.xpath.XPathExpressionException;
32

    
33
import org.apache.commons.codec.EncoderException;
34
import org.apache.commons.lang.StringUtils;
35
import org.dataone.cn.indexer.parser.IDocumentDeleteSubprocessor;
36
import org.dataone.cn.indexer.solrhttp.SolrDoc;
37
import org.dataone.cn.indexer.solrhttp.SolrElementField;
38

    
39
import edu.ucsb.nceas.metacat.index.resourcemap.ResourceMapSubprocessor;
40

    
41

    
42
public class MetacatDocumentDeleteSubprocessor implements IDocumentDeleteSubprocessor {
43

    
44

    
45
    private String relationSourceFormatId;
46
    private String relationSourceField;
47
    private List<String> biDirectionalRelationFields;
48
    private List<String> uniDirectionalRelationFields;
49

    
50
    public MetacatDocumentDeleteSubprocessor() {
51
    }
52

    
53
    public Map<String, SolrDoc> processDocForDelete(String identifier, Map<String, SolrDoc> docs)
54
            throws Exception {
55

    
56
        SolrDoc indexedDoc = ResourceMapSubprocessor.getSolrDoc(identifier);
57
        if (indexedDoc != null) {
58
            if (hasRelationsBySource(indexedDoc)) {
59
                docs.putAll(removeBiDirectionalRelationsForDoc(identifier, indexedDoc, docs));
60
            }
61
            if (isRelationshipSource(indexedDoc)) {
62
                docs.putAll(removeRelationsBySourceDoc(identifier, indexedDoc, docs));
63
            }
64
        }
65
        return docs;
66
    }
67

    
68
    private Map<String, SolrDoc> removeRelationsBySourceDoc(String relationSourceId,
69
            SolrDoc indexedDoc, Map<String, SolrDoc> docs) throws Exception {
70

    
71
        // gather all docs with relations from self source
72
        List<SolrDoc> relatedDocs = ResourceMapSubprocessor.getDocumentsByQuery(
73
                "q=" + relationSourceField + ":\"" + relationSourceId + "\"");
74

    
75
        Set<String> otherSourceDocs = new HashSet<String>();
76

    
77
        for (SolrDoc relatedDoc : relatedDocs) {
78

    
79
            // gather other relation source docs from modified list
80
            otherSourceDocs.addAll(relatedDoc.getAllFieldValues(relationSourceField));
81

    
82
            // remove relation fields (uni and bi-directional)
83
            // add modified docs to update list
84
            String docId = relatedDoc.getFirstFieldValue(SolrElementField.FIELD_ID);
85
            if (docs.get(docId) != null) {
86
                relatedDoc = docs.get(docId);
87
            }
88
            relatedDoc.removeAllFields(relationSourceField);
89
            for (String relationField : getBiDirectionalRelationFields()) {
90
                relatedDoc.removeAllFields(relationField);
91
            }
92
            for (String relationField : getUniDirectionalRelationFields()) {
93
                relatedDoc.removeAllFields(relationField);
94
            }
95
            docs.put(docId, relatedDoc);
96
        }
97

    
98
        for (String otherRelatedDoc : otherSourceDocs) {
99
            if (!otherRelatedDoc.equals(relationSourceId)) {
100
                docs.put(otherRelatedDoc, null);
101
            }
102
        }
103
        return docs;
104
    }
105

    
106
    private boolean isRelationshipSource(SolrDoc indexedDoc) throws Exception {
107
        String formatId = indexedDoc.getFirstFieldValue(SolrElementField.FIELD_OBJECTFORMAT);
108
        return relationSourceFormatId.equals(formatId);
109
    }
110

    
111
    private boolean hasRelationsBySource(SolrDoc indexedDoc) throws XPathExpressionException,
112
            IOException, EncoderException {
113
        String relationSourceId = indexedDoc.getFirstFieldValue(relationSourceField);
114
        return StringUtils.isNotEmpty(relationSourceId);
115
    }
116

    
117
    private Map<String, SolrDoc> removeBiDirectionalRelationsForDoc(String identifier,
118
            SolrDoc indexedDoc, Map<String, SolrDoc> docs) throws Exception {
119

    
120
        for (String relationField : getBiDirectionalRelationFields()) {
121
            List<SolrDoc> inverseDocs = ResourceMapSubprocessor.getDocumentsByQuery(
122
                    "q=" + relationField + ":\"" + identifier + "\"");
123
            for (SolrDoc inverseDoc : inverseDocs) {
124
                String inverseDocId = inverseDoc.getFirstFieldValue(SolrElementField.FIELD_ID);
125
                if (docs.get(inverseDocId) != null) {
126
                    inverseDoc = docs.get(inverseDocId);
127
                }
128
                inverseDoc.removeFieldsWithValue(relationField, identifier);
129
                docs.put(inverseDocId, inverseDoc);
130
            }
131

    
132
        }
133
        return docs;
134
    }
135

    
136
    private List<String> getBiDirectionalRelationFields() {
137
        if (biDirectionalRelationFields == null) {
138
            biDirectionalRelationFields = new ArrayList<String>();
139
        }
140
        return biDirectionalRelationFields;
141
    }
142

    
143
    private List<String> getUniDirectionalRelationFields() {
144
        if (uniDirectionalRelationFields == null) {
145
            uniDirectionalRelationFields = new ArrayList<String>();
146
        }
147
        return uniDirectionalRelationFields;
148
    }
149

    
150
    public String getRelationSourceFormatId() {
151
        return relationSourceFormatId;
152
    }
153

    
154
    public void setRelationSourceFormatId(String relationSourceFormatId) {
155
        this.relationSourceFormatId = relationSourceFormatId;
156
    }
157

    
158
    public String getRelationSourceField() {
159
        return relationSourceField;
160
    }
161

    
162
    public void setRelationSourceField(String relationSourceField) {
163
        this.relationSourceField = relationSourceField;
164
    }
165

    
166
    public void setBiDirectionalRelationFields(List<String> biDirectionalRelationFields) {
167
        this.biDirectionalRelationFields = biDirectionalRelationFields;
168
    }
169

    
170
    public void setUniDirectionalRelationFields(List<String> uniDirectionalRelationFields) {
171
        this.uniDirectionalRelationFields = uniDirectionalRelationFields;
172
    }
173
}
(4-4/7)