Project

General

Profile

Download (8.52 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2016 EDIT
3
* European Distributed Institute of Taxonomy
4
* http://www.e-taxonomy.eu
5
*
6
* The contents of this file are subject to the Mozilla Public License Version 1.1
7
* See LICENSE.TXT at the top of this package for the full license terms.
8
*/
9
package eu.etaxonomy.cdm.api.util;
10

    
11
import java.io.Serializable;
12
import java.util.ArrayList;
13
import java.util.List;
14
import java.util.Map;
15
import java.util.Set;
16

    
17
import org.apache.log4j.Logger;
18
import org.hibernate.FlushMode;
19
import org.hibernate.SQLQuery;
20
import org.hibernate.Session;
21
import org.springframework.beans.factory.annotation.Autowired;
22
import org.springframework.orm.hibernate5.HibernateTransactionManager;
23
import org.springframework.stereotype.Component;
24
import org.springframework.transaction.TransactionDefinition;
25
import org.springframework.transaction.TransactionStatus;
26
import org.springframework.transaction.support.DefaultTransactionDefinition;
27

    
28
import eu.etaxonomy.cdm.api.service.ITaxonService;
29
import eu.etaxonomy.cdm.api.service.UpdateResult;
30
import eu.etaxonomy.cdm.api.service.config.SortIndexUpdaterConfigurator;
31
import eu.etaxonomy.cdm.common.monitor.IProgressMonitor;
32
import eu.etaxonomy.cdm.common.monitor.NullProgressMonitor;
33
import eu.etaxonomy.cdm.common.monitor.SubProgressMonitor;
34
import eu.etaxonomy.cdm.database.update.SortIndexUpdater;
35

    
36
/**
37
 * @author k.luther
38
 * @since 08.07.2016
39
 */
40
@Component
41
public class SortIndexUpdaterWrapper implements Serializable {
42

    
43
    private static final long serialVersionUID = 1152526455024556637L;
44
    private static final Logger logger = Logger.getLogger(SortIndexUpdaterWrapper.class);
45

    
46
    private static final String TAXON_NODE = "TaxonNode";
47
    private static final String TERM_NODE = "TermRelation";
48
    private static final String POLYTOMOUS_KEY_NODE = "PolytomousKeyNode";
49

    
50
    @Autowired
51
    private HibernateTransactionManager transactionManager;
52
//    @Autowired
53
//    private CdmRepository repository;  //TODO not unique therefore byName or so is needed
54
    @Autowired
55
    private ITaxonService repository;
56

    
57
    public UpdateResult doInvoke(SortIndexUpdaterConfigurator config) {
58

    
59
        SortIndexUpdater updater;
60
        UpdateResult result = new UpdateResult();
61
       // CaseType caseType = CaseType.caseTypeOfDatasource(config.getDestination());
62

    
63
        IProgressMonitor  monitor = config.getMonitor();
64
        if (monitor == null){
65
            monitor = new NullProgressMonitor();
66
        }
67

    
68
        if (config.isDoTaxonNode()){
69
            updater = SortIndexUpdater.NewInstance(null, "Update taxon node sortindex", TAXON_NODE, "parent_id", "sortIndex", true);
70

    
71
            result.includeResult(update(updater, monitor));
72
        }
73
        if (config.isDoTermNode()){
74
            updater = SortIndexUpdater.NewInstance(null, "Update term node sortindex", TERM_NODE, "parent_id", "sortIndex", true);
75
            result.includeResult(update(updater, monitor));
76
        }
77
        if (config.isDoPolytomousKeyNode()){
78
            updater = SortIndexUpdater.NewInstance(null, "Update polytomous key node sortindex", POLYTOMOUS_KEY_NODE, "parent_id", "sortindex", true);
79
            result.includeResult(update(updater, monitor));
80
        }
81
        return result;
82
    }
83

    
84
    private UpdateResult update(SortIndexUpdater updater,  IProgressMonitor  monitor){
85

    
86
        //TODO change to long running task result
87
        UpdateResult updateResult = new UpdateResult();
88
        try {
89

    
90
            TransactionStatus tx = startTransaction(true);
91
            String query = updater.createIndexMapQuery();
92
            List<?> data = getSqlResult(query);
93

    
94
            int c = 2;
95
            if (updater.getTableName().equals(TAXON_NODE)){
96
                c= 3;
97
            }
98
            monitor.beginTask("Update index", data.size()*c);
99
            monitor.subTask("Create new index");
100
            IProgressMonitor subMonitor = new SubProgressMonitor(monitor, data.size());
101
            List<Integer[]> result = new ArrayList<>();
102
            int done = 0;
103
            for(Object object : data){
104
                Object[] row = (Object[])object;
105
                Object oId = row[0];
106

    
107
                if (oId != null){
108
                    int id = Integer.valueOf(oId.toString());
109
                    Integer[] rowArray = new Integer[2];
110
                    Object oParentId = row[1];
111
                    if (oParentId != null){
112
                        int parentId = Integer.valueOf(oParentId.toString());
113
                        rowArray[1]= parentId;
114

    
115
                    }else{
116
                        rowArray[1]= null;
117
                    }
118
                    rowArray[0]= id;
119
                    result.add(rowArray);
120
                }
121
                done++;
122
                subMonitor.internalWorked(done);
123
            }
124
            subMonitor.done();
125
            monitor.subTask("update indices");
126

    
127
            Map<Integer, Set<Integer>> indexMap =  updater.makeIndexMap(result);
128
            subMonitor = new SubProgressMonitor(monitor, indexMap.size());
129
            done = 0;
130
            for (Map.Entry<Integer, Set<Integer>> entry: indexMap.entrySet()){
131
                String idSet = SortIndexUpdater.makeIdSetString(entry.getValue());
132
                query = updater.createUpdateIndicesQuery(null,entry.getKey(), idSet);
133
                int resultInt = executeSqlResult(query);
134
                logger.debug("update all indice with index " + entry.getKey() + " - " + resultInt);
135
                done++;
136
                subMonitor.internalWorked(done);
137
            }
138
            subMonitor.done();
139
            //Update childrenCount
140
            if (updater.getTableName().equals(TAXON_NODE)){
141

    
142
                query = updater.getChildrenCountQuery();
143
                data = getSqlResult(query);
144
                subMonitor = new SubProgressMonitor(monitor, data.size());
145
                int realCount;
146
                int countChildren;
147
                int work = 0;
148
                for(Object object : data){
149
                   Object[] row = (Object[])object;
150
                   realCount =  ((Number) row[0]).intValue();
151
                   countChildren = ((Number) row[1]).intValue();
152
                   int id = ((Number) row[2]).intValue();
153

    
154
                   if (realCount != countChildren){
155
                       query = updater.getUpdateChildrenCount(realCount, id);
156
                       int resultInt = executeSqlResult(query);
157
                       logger.debug("update all childrenCount "+ resultInt);
158
                   }
159
                   work ++;
160
                   subMonitor.internalWorked(work);
161
                   subMonitor.done();
162
                 }
163
            }
164
            //TODO: correct handling of updateResult!
165
            monitor.done();
166
            commitTransaction(tx);
167
            return updateResult;
168
        } catch (Exception e) {
169
            monitor.warning("Stopped sortIndex updater");
170
            updateResult.setAbort();
171
            updateResult.addException(e);
172
        }
173
        return null;
174
    }
175

    
176
    private List<?> getSqlResult(String query) {
177
        SQLQuery sqlQuery = getSession().createSQLQuery(query);
178
        List<?> data = sqlQuery.list();
179
        return data;
180
    }
181

    
182
    private int executeSqlResult(String query) {
183
        SQLQuery sqlQuery = getSession().createSQLQuery(query);
184
        return sqlQuery.executeUpdate();
185
    }
186

    
187
    public TransactionStatus startTransaction(Boolean readOnly) {
188

    
189
        DefaultTransactionDefinition defaultTxDef = new DefaultTransactionDefinition();
190
        defaultTxDef.setReadOnly(readOnly);
191
        TransactionDefinition txDef = defaultTxDef;
192

    
193
        // Log some transaction-related debug information.
194
        if (logger.isTraceEnabled()) {
195
            logger.trace("Transaction name = " + txDef.getName());
196
            logger.trace("Transaction facets:");
197
            logger.trace("Propagation behavior = " + txDef.getPropagationBehavior());
198
            logger.trace("Isolation level = " + txDef.getIsolationLevel());
199
            logger.trace("Timeout = " + txDef.getTimeout());
200
            logger.trace("Read Only = " + txDef.isReadOnly());
201
            // org.springframework.orm.hibernate5.HibernateTransactionManager
202
            // provides more transaction/session-related debug information.
203
        }
204

    
205
        TransactionStatus txStatus = transactionManager.getTransaction(txDef);
206

    
207
        //TODO is this really necessary
208
        getSession().setFlushMode(FlushMode.COMMIT);
209

    
210
        return txStatus;
211
    }
212

    
213
    private Session getSession() {
214
        return repository.getSession();
215
    }
216

    
217
    public void commitTransaction(TransactionStatus txStatus){
218
        logger.debug("commiting transaction ...");
219
        transactionManager.commit(txStatus);
220
        return;
221
    }
222

    
223
}
(15-15/18)