Project

General

Profile

« Previous | Next » 

Revision ac5020e6

Added by Andreas Müller about 8 years ago

Fix CCE in DefinedTermDaoImpl.getPartOf (#5556) and make deproxy more
generic

View differences:

cdmlib-io/src/main/java/eu/etaxonomy/cdm/io/jaxb/JaxbExport.java
1
/**
2
 * Copyright (C) 2008 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

  
10
package eu.etaxonomy.cdm.io.jaxb;
11

  
12
import java.io.ByteArrayOutputStream;
13
import java.io.File;
14
import java.io.FileNotFoundException;
15
import java.io.FileOutputStream;
16
import java.io.OutputStreamWriter;
17
import java.io.PrintWriter;
18
import java.io.UnsupportedEncodingException;
19
import java.net.URI;
20
import java.util.ArrayList;
21
import java.util.List;
22

  
23
import javax.xml.transform.stream.StreamResult;
24

  
25
import org.apache.log4j.Logger;
26
import org.springframework.stereotype.Component;
27
import org.springframework.transaction.TransactionStatus;
28

  
29
import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
30
import eu.etaxonomy.cdm.io.common.CdmExportBase;
31
import eu.etaxonomy.cdm.io.common.ICdmExport;
32
import eu.etaxonomy.cdm.io.common.IExportConfigurator;
33
import eu.etaxonomy.cdm.io.common.mapping.out.IExportTransformer;
34
import eu.etaxonomy.cdm.model.agent.AgentBase;
35
import eu.etaxonomy.cdm.model.common.DefinedTermBase;
36
import eu.etaxonomy.cdm.model.common.User;
37
import eu.etaxonomy.cdm.model.description.FeatureTree;
38
import eu.etaxonomy.cdm.model.name.TaxonNameBase;
39
import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
40
import eu.etaxonomy.cdm.model.reference.Reference;
41
import eu.etaxonomy.cdm.model.taxon.Classification;
42
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
43
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
44

  
45
/**
46
 * @author a.babadshanjan
47
 * @created 25.09.2008
48
 * @version 1.0
49
 */
50
@Component
51
public class JaxbExport extends CdmExportBase<JaxbExportConfigurator, JaxbExportState, IExportTransformer> implements ICdmExport<JaxbExportConfigurator, JaxbExportState> {
52

  
53
    private static final Logger logger = Logger.getLogger(JaxbExport.class);
54

  
55
    private DataSet dataSet;
56

  
57

  
58
    //	/**
59
    //	 *
60
    //	 */
61
    //	public JaxbExport() {
62
    //		super();
63
    //		this.ioName = this.getClass().getSimpleName();
64
    //	}
65

  
66
    /** Retrieves data from a CDM DB and serializes them CDM to XML.
67
     * Starts with root taxa and traverses the classification to retrieve children taxa, synonyms and relationships.
68
     * Taxa that are not part of the classification are not found.
69
     *
70
     * @param exImpConfig
71
     * @param dbname
72
     * @param filename
73
     */
74
    //	@Override
75
    //	protected boolean doInvoke(IExportConfigurator config,
76
    //			Map<String, MapWrapper<? extends CdmBase>> stores) {
77
    @Override
78
    protected void doInvoke(JaxbExportState state) {
79

  
80
        JaxbExportConfigurator jaxbExpConfig = (JaxbExportConfigurator)state.getConfig();
81
        //		String dbname = jaxbExpConfig.getSource().getName();
82
        URI uri = jaxbExpConfig.getDestination();
83
        //		logger.info("Serializing DB " + dbname + " to file " + fileName);
84
        //		logger.debug("DbSchemaValidation = " + jaxbExpConfig.getDbSchemaValidation());
85

  
86
        TransactionStatus txStatus = null;
87

  
88
        txStatus = startTransaction(true);
89

  
90
        dataSet = new DataSet();
91

  
92
        // get data from DB
93

  
94
        try {
95
            logger.info("Retrieving data from DB");
96

  
97
            retrieveData(jaxbExpConfig, dataSet);
98

  
99
        } catch (Exception e) {
100
            logger.error("Error retrieving data");
101
            e.printStackTrace();
102
        }
103

  
104
        logger.info("All data retrieved");
105

  
106
        try {
107
            switch(jaxbExpConfig.getTarget()) {
108
            case FILE:
109
                writeToFile(new File(uri), dataSet);
110
                break;
111
            case EXPORT_DATA:
112
                CdmDocumentBuilder cdmDocumentBuilder = new CdmDocumentBuilder();
113
                exportStream = new ByteArrayOutputStream();
114
                cdmDocumentBuilder.marshal(dataSet, new StreamResult(exportStream));
115
                break;
116
            default:
117
                break;
118
            }
119
        } catch (Exception e) {
120
            logger.error("Marshalling error");
121
            e.printStackTrace();
122
        }
123

  
124
        commitTransaction(txStatus);
125

  
126
        return;
127

  
128
    }
129

  
130
    public static void writeToFile(File file, DataSet dataSet) throws UnsupportedEncodingException, FileNotFoundException {
131
        CdmDocumentBuilder cdmDocumentBuilder = new CdmDocumentBuilder();
132
        PrintWriter writer = new PrintWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF8"), true);
133
        cdmDocumentBuilder.marshal(dataSet, writer);
134

  
135
        // TODO: Split into one file per data set member to see whether performance improves?
136

  
137
        logger.info("XML file written");
138
        logger.info("Filename is: " + file.getAbsolutePath());
139
    }
140

  
141
    private void retrieveData (IExportConfigurator config, DataSet dataSet) {
142

  
143
        JaxbExportConfigurator jaxbExpConfig = (JaxbExportConfigurator)config;
144
        final int MAX_ROWS = 50000;
145
        int numberOfRows = jaxbExpConfig.getMaxRows();
146

  
147
        int agentRows = numberOfRows;
148
        int definedTermBaseRows = numberOfRows;
149
        int referenceBaseRows = numberOfRows;
150
        int taxonNameBaseRows = numberOfRows;
151
        int taxonBaseRows = numberOfRows;
152
        int taxonNodeRows = numberOfRows;
153
        int relationshipRows = numberOfRows;
154
        int occurrencesRows = numberOfRows;
155
        int mediaRows = numberOfRows;
156
        int featureDataRows = numberOfRows;
157
        int classificationDataRows = numberOfRows;
158
        int languageDataRows = numberOfRows;
159
        int termVocabularyRows = numberOfRows;
160
        int homotypicalGroupRows = numberOfRows;
161
        int UserRows= numberOfRows;
162

  
163
        if (jaxbExpConfig.isDoUsers() == true) {
164

  
165
            if (UserRows == 0) { UserRows = MAX_ROWS; }
166
            logger.info("# User");
167
            List<User> users = getUserService().list(null, UserRows, 0, null, null);
168

  
169

  
170
            for (User user: users){
171
                dataSet.addUser( (User)HibernateProxyHelper.deproxy(user));
172
            }
173

  
174
        }
175
        if (jaxbExpConfig.isDoTermVocabularies() == true) {
176
            if (termVocabularyRows == 0) { termVocabularyRows = MAX_ROWS; }
177
            logger.info("# TermVocabulary");
178
            dataSet.setTermVocabularies((List)getVocabularyService().list(null,termVocabularyRows, 0, null, null));
179
        }
180

  
181

  
182

  
183
        //		if (jaxbExpConfig.isDoLanguageData() == true) {
184
        //			if (languageDataRows == 0) { languageDataRows = MAX_ROWS; }
185
        //			logger.info("# Representation, Language String");
186
        //			dataSet.setLanguageData(getTermService().getAllRepresentations(MAX_ROWS, 0));
187
        //TODO!!!
188
        dataSet.setLanguageStrings(getTermService().getAllLanguageStrings(MAX_ROWS, 0));
189
        //		}
190

  
191
        if (jaxbExpConfig.isDoTerms() == true) {
192
            if (definedTermBaseRows == 0) { definedTermBaseRows = getTermService().count(DefinedTermBase.class); }
193
            logger.info("# DefinedTermBase: " + definedTermBaseRows);
194
            dataSet.setTerms(getTermService().list(null,definedTermBaseRows, 0,null,null));
195
        }
196

  
197
        if (jaxbExpConfig.isDoAuthors() == true) {
198
            if (agentRows == 0) { agentRows = getAgentService().count(AgentBase.class); }
199
            logger.info("# Agents: " + agentRows);
200
            //logger.info("    # Team: " + appCtr.getAgentService().count(Team.class));
201
            dataSet.setAgents(getAgentService().list(null,agentRows, 0,null,null));
202
        }
203

  
204

  
205

  
206
        if (jaxbExpConfig.getDoReferences() != IExportConfigurator.DO_REFERENCES.NONE) {
207
            if (referenceBaseRows == 0) { referenceBaseRows = getReferenceService().count(Reference.class); }
208
            logger.info("# Reference: " + referenceBaseRows);
209
            dataSet.setReferences(getReferenceService().list(null,referenceBaseRows, 0,null,null));
210
        }
211

  
212
        if (jaxbExpConfig.isDoHomotypicalGroups() == true) {
213
            if (homotypicalGroupRows == 0) { homotypicalGroupRows = MAX_ROWS; }
214
            logger.info("# Homotypical Groups");
215
            dataSet.setHomotypicalGroups(getNameService().getAllHomotypicalGroups(homotypicalGroupRows, 0));
216
        }
217

  
218
        if (jaxbExpConfig.isDoTaxonNames() == true) {
219
            if (taxonNameBaseRows == 0) { taxonNameBaseRows = getNameService().count(TaxonNameBase.class); }
220
            logger.info("# TaxonNameBase: " + taxonNameBaseRows);
221
            //logger.info("    # Taxon: " + getNameService().count(BotanicalName.class));
222
            dataSet.setTaxonomicNames(getNameService().list(null,taxonNameBaseRows, 0,null,null));
223
        }
224

  
225

  
226

  
227
        if (jaxbExpConfig.isDoTaxa() == true) {
228
            if (taxonBaseRows == 0) { taxonBaseRows = getTaxonService().count(TaxonBase.class); }
229
            logger.info("# TaxonBase: " + taxonBaseRows);
230
            //			dataSet.setTaxa(new ArrayList<Taxon>());
231
            //			dataSet.setSynonyms(new ArrayList<Synonym>());
232
            List<TaxonBase> tb = getTaxonService().list(null,taxonBaseRows, 0,null,null);
233
            for (TaxonBase taxonBase : tb) {
234
                dataSet.addTaxonBase((TaxonBase)HibernateProxyHelper.deproxy(taxonBase));
235
            }
236
        }
237

  
238
        // TODO:
239
        // retrieve taxa and synonyms separately
240
        // need correct count for taxa and synonyms
241
        //		if (taxonBaseRows == 0) { taxonBaseRows = getTaxonService().count(TaxonBase.class); }
242
        //		logger.info("# Synonym: " + taxonBaseRows);
243
        //		dataSet.setSynonyms(new ArrayList<Synonym>());
244
        //		dataSet.setSynonyms(getTaxonService().getAllSynonyms(taxonBaseRows, 0));
245

  
246
        //		if (jaxbExpConfig.isDoRelTaxa() == true) {
247
        //			if (relationshipRows == 0) { relationshipRows = MAX_ROWS; }
248
        //			logger.info("# Relationships");
249
        //			List<RelationshipBase> relationList = getTaxonService().getAllRelationships(relationshipRows, 0);
250
        //			Set<RelationshipBase> relationSet = new HashSet<RelationshipBase>(relationList);
251
        //			dataSet.setRelationships(relationSet);
252
        //		}
253
        if (jaxbExpConfig.isDoOccurrence() == true) {
254
            if (occurrencesRows == 0) { occurrencesRows = getOccurrenceService().count(SpecimenOrObservationBase.class); }
255
            logger.info("# SpecimenOrObservationBase: " + occurrencesRows);
256
            List<SpecimenOrObservationBase> occurrenceList = getOccurrenceService().list(null,occurrencesRows, 0,null,null);
257
            /*List<SpecimenOrObservationBase> noProxyList = new ArrayList<SpecimenOrObservationBase>();
258
			for (SpecimenOrObservationBase specimen : occurrenceList){
259
				specimen = (SpecimenOrObservationBase)HibernateProxyHelper.deproxy(specimen);
260
				noProxyList.add(specimen);
261
			}*/
262
            dataSet.setOccurrences(occurrenceList);
263
        }
264

  
265
        if (jaxbExpConfig.isDoTypeDesignations() == true) {
266
            logger.info("# TypeDesignations");
267
            dataSet.addTypeDesignations(getNameService().getAllTypeDesignations(MAX_ROWS, 0));
268
        }
269

  
270

  
271

  
272
        if (jaxbExpConfig.isDoMedia() == true) {
273
            if (mediaRows == 0) { mediaRows = MAX_ROWS; }
274
            logger.info("# Media");
275
            dataSet.setMedia(getMediaService().list(null,mediaRows, 0,null,null));
276
            //			dataSet.addMedia(getMediaService().getAllMediaRepresentations(mediaRows, 0));
277
            //			dataSet.addMedia(getMediaService().getAllMediaRepresentationParts(mediaRows, 0));
278
        }
279

  
280
        if (jaxbExpConfig.isDoFeatureData() == true) {
281
            if (featureDataRows == 0) { featureDataRows = MAX_ROWS; }
282
            logger.info("# Feature Tree, Feature Node");
283
            List<FeatureTree> featureTrees = new ArrayList<FeatureTree>();
284
            featureTrees= getFeatureTreeService().list(null,featureDataRows, 0, null, null);
285
            List<FeatureTree> taxTreesdeproxy = new ArrayList<FeatureTree>();
286
            for (FeatureTree featureTree : featureTrees){
287
                HibernateProxyHelper.deproxy(featureTree);
288
                taxTreesdeproxy.add(featureTree);
289
            }
290

  
291
            dataSet.setFeatureTrees(getFeatureTreeService().list(null,null,null,null,null));
292
        }
293
        if (jaxbExpConfig.isDoClassificationData() == true) {
294
            if (classificationDataRows == 0) { classificationDataRows = MAX_ROWS; }
295
            logger.info("# Classification");
296

  
297

  
298
            List<Classification> taxTrees = new ArrayList<Classification>();
299
            taxTrees= getClassificationService().list(null,classificationDataRows, 0, null, null);
300

  
301
            List<Classification> taxTreesdeproxy = new ArrayList<Classification>();
302
            for (Classification taxTree : taxTrees){
303
                HibernateProxyHelper.deproxy(taxTree);
304
                taxTreesdeproxy.add(taxTree);
305
            }
306
            List<TaxonNode> taxNodes = new ArrayList<TaxonNode>();
307
            taxNodes= getClassificationService().getAllNodes();
308
            List<TaxonNode> taxNodesdeproxy = new ArrayList<TaxonNode>();
309
            for (TaxonNode taxNode : taxNodes){
310
                HibernateProxyHelper.deproxy(taxNode);
311
                taxNodesdeproxy.add(taxNode);
312
            }
313

  
314
            dataSet.setTaxonNodes(taxNodesdeproxy);
315
            dataSet.setClassifications(taxTreesdeproxy );
316
        }
317
        //TODO: FIXME!!!!!
318
        dataSet.setLanguageStrings(null);
319
    }
320

  
321

  
322
    @Override
323
    protected boolean doCheck(JaxbExportState state) {
324
        boolean result = true;
325
        logger.warn("No check implemented for Jaxb export");
326
        return result;
327
    }
328

  
329

  
330
    @Override
331
    protected boolean isIgnore(JaxbExportState state) {
332
        return false;
333
    }
334

  
335
}
1
/**
2
 * Copyright (C) 2008 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

  
10
package eu.etaxonomy.cdm.io.jaxb;
11

  
12
import java.io.ByteArrayOutputStream;
13
import java.io.File;
14
import java.io.FileNotFoundException;
15
import java.io.FileOutputStream;
16
import java.io.OutputStreamWriter;
17
import java.io.PrintWriter;
18
import java.io.UnsupportedEncodingException;
19
import java.net.URI;
20
import java.util.ArrayList;
21
import java.util.List;
22

  
23
import javax.xml.transform.stream.StreamResult;
24

  
25
import org.apache.log4j.Logger;
26
import org.springframework.stereotype.Component;
27
import org.springframework.transaction.TransactionStatus;
28

  
29
import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
30
import eu.etaxonomy.cdm.io.common.CdmExportBase;
31
import eu.etaxonomy.cdm.io.common.ICdmExport;
32
import eu.etaxonomy.cdm.io.common.IExportConfigurator;
33
import eu.etaxonomy.cdm.io.common.mapping.out.IExportTransformer;
34
import eu.etaxonomy.cdm.model.agent.AgentBase;
35
import eu.etaxonomy.cdm.model.common.DefinedTermBase;
36
import eu.etaxonomy.cdm.model.common.User;
37
import eu.etaxonomy.cdm.model.description.FeatureTree;
38
import eu.etaxonomy.cdm.model.name.TaxonNameBase;
39
import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
40
import eu.etaxonomy.cdm.model.reference.Reference;
41
import eu.etaxonomy.cdm.model.taxon.Classification;
42
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
43
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
44

  
45
/**
46
 * @author a.babadshanjan
47
 * @created 25.09.2008
48
 * @version 1.0
49
 */
50
@Component
51
public class JaxbExport extends CdmExportBase<JaxbExportConfigurator, JaxbExportState, IExportTransformer> implements ICdmExport<JaxbExportConfigurator, JaxbExportState> {
52

  
53
    private static final Logger logger = Logger.getLogger(JaxbExport.class);
54

  
55
    private DataSet dataSet;
56

  
57

  
58
    //	/**
59
    //	 *
60
    //	 */
61
    //	public JaxbExport() {
62
    //		super();
63
    //		this.ioName = this.getClass().getSimpleName();
64
    //	}
65

  
66
    /** Retrieves data from a CDM DB and serializes them CDM to XML.
67
     * Starts with root taxa and traverses the classification to retrieve children taxa, synonyms and relationships.
68
     * Taxa that are not part of the classification are not found.
69
     *
70
     * @param exImpConfig
71
     * @param dbname
72
     * @param filename
73
     */
74
    //	@Override
75
    //	protected boolean doInvoke(IExportConfigurator config,
76
    //			Map<String, MapWrapper<? extends CdmBase>> stores) {
77
    @Override
78
    protected void doInvoke(JaxbExportState state) {
79

  
80
        JaxbExportConfigurator jaxbExpConfig = (JaxbExportConfigurator)state.getConfig();
81
        //		String dbname = jaxbExpConfig.getSource().getName();
82
        URI uri = jaxbExpConfig.getDestination();
83
        //		logger.info("Serializing DB " + dbname + " to file " + fileName);
84
        //		logger.debug("DbSchemaValidation = " + jaxbExpConfig.getDbSchemaValidation());
85

  
86
        TransactionStatus txStatus = null;
87

  
88
        txStatus = startTransaction(true);
89

  
90
        dataSet = new DataSet();
91

  
92
        // get data from DB
93

  
94
        try {
95
            logger.info("Retrieving data from DB");
96

  
97
            retrieveData(jaxbExpConfig, dataSet);
98

  
99
        } catch (Exception e) {
100
            logger.error("Error retrieving data");
101
            e.printStackTrace();
102
        }
103

  
104
        logger.info("All data retrieved");
105

  
106
        try {
107
            switch(jaxbExpConfig.getTarget()) {
108
            case FILE:
109
                writeToFile(new File(uri), dataSet);
110
                break;
111
            case EXPORT_DATA:
112
                CdmDocumentBuilder cdmDocumentBuilder = new CdmDocumentBuilder();
113
                exportStream = new ByteArrayOutputStream();
114
                cdmDocumentBuilder.marshal(dataSet, new StreamResult(exportStream));
115
                break;
116
            default:
117
                break;
118
            }
119
        } catch (Exception e) {
120
            logger.error("Marshalling error");
121
            e.printStackTrace();
122
        }
123

  
124
        commitTransaction(txStatus);
125

  
126
        return;
127

  
128
    }
129

  
130
    public static void writeToFile(File file, DataSet dataSet) throws UnsupportedEncodingException, FileNotFoundException {
131
        CdmDocumentBuilder cdmDocumentBuilder = new CdmDocumentBuilder();
132
        PrintWriter writer = new PrintWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF8"), true);
133
        cdmDocumentBuilder.marshal(dataSet, writer);
134

  
135
        // TODO: Split into one file per data set member to see whether performance improves?
136

  
137
        logger.info("XML file written");
138
        logger.info("Filename is: " + file.getAbsolutePath());
139
    }
140

  
141
    private void retrieveData (IExportConfigurator config, DataSet dataSet) {
142

  
143
        JaxbExportConfigurator jaxbExpConfig = (JaxbExportConfigurator)config;
144
        final int MAX_ROWS = 50000;
145
        int numberOfRows = jaxbExpConfig.getMaxRows();
146

  
147
        int agentRows = numberOfRows;
148
        int definedTermBaseRows = numberOfRows;
149
        int referenceBaseRows = numberOfRows;
150
        int taxonNameBaseRows = numberOfRows;
151
        int taxonBaseRows = numberOfRows;
152
        int taxonNodeRows = numberOfRows;
153
        int relationshipRows = numberOfRows;
154
        int occurrencesRows = numberOfRows;
155
        int mediaRows = numberOfRows;
156
        int featureDataRows = numberOfRows;
157
        int classificationDataRows = numberOfRows;
158
        int languageDataRows = numberOfRows;
159
        int termVocabularyRows = numberOfRows;
160
        int homotypicalGroupRows = numberOfRows;
161
        int UserRows= numberOfRows;
162

  
163
        if (jaxbExpConfig.isDoUsers() == true) {
164

  
165
            if (UserRows == 0) { UserRows = MAX_ROWS; }
166
            logger.info("# User");
167
            List<User> users = getUserService().list(null, UserRows, 0, null, null);
168

  
169

  
170
            for (User user: users){
171
                dataSet.addUser(HibernateProxyHelper.deproxy(user));
172
            }
173

  
174
        }
175
        if (jaxbExpConfig.isDoTermVocabularies() == true) {
176
            if (termVocabularyRows == 0) { termVocabularyRows = MAX_ROWS; }
177
            logger.info("# TermVocabulary");
178
            dataSet.setTermVocabularies((List)getVocabularyService().list(null,termVocabularyRows, 0, null, null));
179
        }
180

  
181

  
182

  
183
        //		if (jaxbExpConfig.isDoLanguageData() == true) {
184
        //			if (languageDataRows == 0) { languageDataRows = MAX_ROWS; }
185
        //			logger.info("# Representation, Language String");
186
        //			dataSet.setLanguageData(getTermService().getAllRepresentations(MAX_ROWS, 0));
187
        //TODO!!!
188
        dataSet.setLanguageStrings(getTermService().getAllLanguageStrings(MAX_ROWS, 0));
189
        //		}
190

  
191
        if (jaxbExpConfig.isDoTerms() == true) {
192
            if (definedTermBaseRows == 0) { definedTermBaseRows = getTermService().count(DefinedTermBase.class); }
193
            logger.info("# DefinedTermBase: " + definedTermBaseRows);
194
            dataSet.setTerms(getTermService().list(null,definedTermBaseRows, 0,null,null));
195
        }
196

  
197
        if (jaxbExpConfig.isDoAuthors() == true) {
198
            if (agentRows == 0) { agentRows = getAgentService().count(AgentBase.class); }
199
            logger.info("# Agents: " + agentRows);
200
            //logger.info("    # Team: " + appCtr.getAgentService().count(Team.class));
201
            dataSet.setAgents(getAgentService().list(null,agentRows, 0,null,null));
202
        }
203

  
204

  
205

  
206
        if (jaxbExpConfig.getDoReferences() != IExportConfigurator.DO_REFERENCES.NONE) {
207
            if (referenceBaseRows == 0) { referenceBaseRows = getReferenceService().count(Reference.class); }
208
            logger.info("# Reference: " + referenceBaseRows);
209
            dataSet.setReferences(getReferenceService().list(null,referenceBaseRows, 0,null,null));
210
        }
211

  
212
        if (jaxbExpConfig.isDoHomotypicalGroups() == true) {
213
            if (homotypicalGroupRows == 0) { homotypicalGroupRows = MAX_ROWS; }
214
            logger.info("# Homotypical Groups");
215
            dataSet.setHomotypicalGroups(getNameService().getAllHomotypicalGroups(homotypicalGroupRows, 0));
216
        }
217

  
218
        if (jaxbExpConfig.isDoTaxonNames() == true) {
219
            if (taxonNameBaseRows == 0) { taxonNameBaseRows = getNameService().count(TaxonNameBase.class); }
220
            logger.info("# TaxonNameBase: " + taxonNameBaseRows);
221
            //logger.info("    # Taxon: " + getNameService().count(BotanicalName.class));
222
            dataSet.setTaxonomicNames(getNameService().list(null,taxonNameBaseRows, 0,null,null));
223
        }
224

  
225

  
226

  
227
        if (jaxbExpConfig.isDoTaxa() == true) {
228
            if (taxonBaseRows == 0) { taxonBaseRows = getTaxonService().count(TaxonBase.class); }
229
            logger.info("# TaxonBase: " + taxonBaseRows);
230
            //			dataSet.setTaxa(new ArrayList<Taxon>());
231
            //			dataSet.setSynonyms(new ArrayList<Synonym>());
232
            List<TaxonBase> tb = getTaxonService().list(null,taxonBaseRows, 0,null,null);
233
            for (TaxonBase taxonBase : tb) {
234
                dataSet.addTaxonBase(HibernateProxyHelper.deproxy(taxonBase));
235
            }
236
        }
237

  
238
        // TODO:
239
        // retrieve taxa and synonyms separately
240
        // need correct count for taxa and synonyms
241
        //		if (taxonBaseRows == 0) { taxonBaseRows = getTaxonService().count(TaxonBase.class); }
242
        //		logger.info("# Synonym: " + taxonBaseRows);
243
        //		dataSet.setSynonyms(new ArrayList<Synonym>());
244
        //		dataSet.setSynonyms(getTaxonService().getAllSynonyms(taxonBaseRows, 0));
245

  
246
        //		if (jaxbExpConfig.isDoRelTaxa() == true) {
247
        //			if (relationshipRows == 0) { relationshipRows = MAX_ROWS; }
248
        //			logger.info("# Relationships");
249
        //			List<RelationshipBase> relationList = getTaxonService().getAllRelationships(relationshipRows, 0);
250
        //			Set<RelationshipBase> relationSet = new HashSet<RelationshipBase>(relationList);
251
        //			dataSet.setRelationships(relationSet);
252
        //		}
253
        if (jaxbExpConfig.isDoOccurrence() == true) {
254
            if (occurrencesRows == 0) { occurrencesRows = getOccurrenceService().count(SpecimenOrObservationBase.class); }
255
            logger.info("# SpecimenOrObservationBase: " + occurrencesRows);
256
            List<SpecimenOrObservationBase> occurrenceList = getOccurrenceService().list(null,occurrencesRows, 0,null,null);
257
            /*List<SpecimenOrObservationBase> noProxyList = new ArrayList<SpecimenOrObservationBase>();
258
			for (SpecimenOrObservationBase specimen : occurrenceList){
259
				specimen = (SpecimenOrObservationBase)HibernateProxyHelper.deproxy(specimen);
260
				noProxyList.add(specimen);
261
			}*/
262
            dataSet.setOccurrences(occurrenceList);
263
        }
264

  
265
        if (jaxbExpConfig.isDoTypeDesignations() == true) {
266
            logger.info("# TypeDesignations");
267
            dataSet.addTypeDesignations(getNameService().getAllTypeDesignations(MAX_ROWS, 0));
268
        }
269

  
270

  
271

  
272
        if (jaxbExpConfig.isDoMedia() == true) {
273
            if (mediaRows == 0) { mediaRows = MAX_ROWS; }
274
            logger.info("# Media");
275
            dataSet.setMedia(getMediaService().list(null,mediaRows, 0,null,null));
276
            //			dataSet.addMedia(getMediaService().getAllMediaRepresentations(mediaRows, 0));
277
            //			dataSet.addMedia(getMediaService().getAllMediaRepresentationParts(mediaRows, 0));
278
        }
279

  
280
        if (jaxbExpConfig.isDoFeatureData() == true) {
281
            if (featureDataRows == 0) { featureDataRows = MAX_ROWS; }
282
            logger.info("# Feature Tree, Feature Node");
283
            List<FeatureTree> featureTrees = new ArrayList<FeatureTree>();
284
            featureTrees= getFeatureTreeService().list(null,featureDataRows, 0, null, null);
285
            List<FeatureTree> taxTreesdeproxy = new ArrayList<FeatureTree>();
286
            for (FeatureTree featureTree : featureTrees){
287
                HibernateProxyHelper.deproxy(featureTree);
288
                taxTreesdeproxy.add(featureTree);
289
            }
290

  
291
            dataSet.setFeatureTrees(getFeatureTreeService().list(null,null,null,null,null));
292
        }
293
        if (jaxbExpConfig.isDoClassificationData() == true) {
294
            if (classificationDataRows == 0) { classificationDataRows = MAX_ROWS; }
295
            logger.info("# Classification");
296

  
297

  
298
            List<Classification> taxTrees = new ArrayList<Classification>();
299
            taxTrees= getClassificationService().list(null,classificationDataRows, 0, null, null);
300

  
301
            List<Classification> taxTreesdeproxy = new ArrayList<Classification>();
302
            for (Classification taxTree : taxTrees){
303
                HibernateProxyHelper.deproxy(taxTree);
304
                taxTreesdeproxy.add(taxTree);
305
            }
306
            List<TaxonNode> taxNodes = new ArrayList<TaxonNode>();
307
            taxNodes= getClassificationService().getAllNodes();
308
            List<TaxonNode> taxNodesdeproxy = new ArrayList<TaxonNode>();
309
            for (TaxonNode taxNode : taxNodes){
310
                HibernateProxyHelper.deproxy(taxNode);
311
                taxNodesdeproxy.add(taxNode);
312
            }
313

  
314
            dataSet.setTaxonNodes(taxNodesdeproxy);
315
            dataSet.setClassifications(taxTreesdeproxy );
316
        }
317
        //TODO: FIXME!!!!!
318
        dataSet.setLanguageStrings(null);
319
    }
320

  
321

  
322
    @Override
323
    protected boolean doCheck(JaxbExportState state) {
324
        boolean result = true;
325
        logger.warn("No check implemented for Jaxb export");
326
        return result;
327
    }
328

  
329

  
330
    @Override
331
    protected boolean isIgnore(JaxbExportState state) {
332
        return false;
333
    }
334

  
335
}
cdmlib-model/src/main/java/eu/etaxonomy/cdm/hibernate/HibernateProxyHelper.java
12 12
import java.io.Serializable;
13 13

  
14 14
import org.apache.log4j.Logger;
15
import org.hibernate.Hibernate;
15 16
import org.hibernate.proxy.HibernateProxy;
16
import org.hibernate.proxy.LazyInitializer;
17 17

  
18 18
/**
19 19
 * @author a.mueller
......
34 34
	     }
35 35
	 }
36 36

  
37
		/**
38
		 * Unwrap the target instance from the proxy.
39
		 */
40
		public static Object deproxy(Object object){
41
			if(object instanceof HibernateProxy) {
42
				LazyInitializer lazyInitializer = ((HibernateProxy)object).getHibernateLazyInitializer();
43
				return lazyInitializer.getImplementation();
44
			} else {
45
				return object;
46
			}
47
		}
37
	 /**
38
	  * Unwrap the target instance from the proxy.
39
	  */
40
	 public static <T> T deproxy(T entity){
41
	     if (entity == null){
42
	         return null;
43
	     }
44
	     if(entity instanceof HibernateProxy) {
45
	         Hibernate.initialize(entity);
46
	         entity = (T) ((HibernateProxy) entity).getHibernateLazyInitializer().getImplementation();
47
	     }
48
	     return entity;
49
	}
48 50

  
49 51

  
50 52
	public static boolean isInstanceOf(Object object, Class clazz) throws ClassCastException {
cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/common/CdmBase.java
290 290
    }
291 291

  
292 292
// ************************** Hibernate proxies *******************/
293

  
294
    /**
295
     * If entity is a HibernateProxy it returns the initialized object.
296
     * Otherwise entity itself is returned.
297
     * @param entity
298
     * @return
299
     * @throws ClassCastException
300
     */
301
    public static <T> T deproxy(T entity) {
302
        return HibernateProxyHelper.deproxy(entity);
303
    }
304

  
293 305
    /**
294 306
     * These methods are present due to HHH-1517 - that in a one-to-many
295 307
     * relationship with a superclass at the "one" end, the proxy created
cdmlib-model/src/main/java/eu/etaxonomy/cdm/strategy/match/DefaultMatchStrategy.java
1
// $Id$
2
/**
3
* Copyright (C) 2007 EDIT
4
* European Distributed Institute of Taxonomy 
5
* http://www.e-taxonomy.eu
6
* 
7
* The contents of this file are subject to the Mozilla Public License Version 1.1
8
* See LICENSE.TXT at the top of this package for the full license terms.
9
*/
10

  
11
package eu.etaxonomy.cdm.strategy.match;
12

  
13
import java.lang.annotation.Annotation;
14
import java.lang.reflect.Field;
15
import java.lang.reflect.GenericDeclaration;
16
import java.lang.reflect.ParameterizedType;
17
import java.lang.reflect.Type;
18
import java.lang.reflect.TypeVariable;
19
import java.net.URI;
20
import java.util.ArrayList;
21
import java.util.Collection;
22
import java.util.HashMap;
23
import java.util.List;
24
import java.util.Map;
25
import java.util.Set;
26
import java.util.UUID;
27

  
28
import org.apache.commons.lang.StringUtils;
29
import org.apache.log4j.Logger;
30

  
31
import eu.etaxonomy.cdm.common.CdmUtils;
32
import eu.etaxonomy.cdm.common.DOI;
33
import eu.etaxonomy.cdm.common.DoubleResult;
34
import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
35
import eu.etaxonomy.cdm.model.common.CdmBase;
36
import eu.etaxonomy.cdm.strategy.StrategyBase;
37
import eu.etaxonomy.cdm.strategy.match.Match.ReplaceMode;
38

  
39
/**
40
 * @author a.mueller
41
 * @created 06.08.2009
42
 * @version 1.0
43
 */
44
public class DefaultMatchStrategy extends StrategyBase implements IMatchStrategy {
45
	private static final long serialVersionUID = 5045874493910155162L;
46
	private static final Logger logger = Logger.getLogger(DefaultMatchStrategy.class);
47

  
48
	final static UUID uuid = UUID.fromString("69467b70-07ec-43a6-b779-3ec8d013837b");
49
	
50
	public static DefaultMatchStrategy NewInstance(Class<? extends IMatchable> matchClazz){
51
		return new DefaultMatchStrategy(matchClazz);
52
	}
53
	
54
//	protected Map<String, MatchMode> matchModeMap = new HashMap<String, MatchMode>();
55
	protected MatchMode defaultMatchMode = MatchMode.EQUAL;
56
	protected MatchMode defaultCollectionMatchMode = MatchMode.IGNORE;
57
	protected MatchMode defaultMatchMatchMode = MatchMode.MATCH;
58
	
59
	protected Class<? extends IMatchable> matchClass;
60
	protected Map<String, Field> matchFields;
61
	protected Matching matching = new Matching();
62
	
63
	protected DefaultMatchStrategy(Class<? extends IMatchable> matchClazz) {
64
		super();
65
		if (matchClazz == null){
66
			throw new IllegalArgumentException("Match class must not be null");
67
		}
68
		this.matchClass = matchClazz;
69
		initMapping();
70
	}
71
	
72
	/**
73
	 * @return the merge class
74
	 */
75
	public Class<? extends IMatchable> getMatchClass() {
76
		return matchClass;
77
	}
78

  
79
	/* (non-Javadoc)
80
	 * @see eu.etaxonomy.cdm.strategy.StrategyBase#getUuid()
81
	 */
82
	@Override
83
	protected UUID getUuid() {
84
		return uuid;
85
	}
86
	
87
	/* (non-Javadoc)
88
	 * @see eu.etaxonomy.cdm.strategy.match.IMatchStrategy#getMatching()
89
	 */
90
	public Matching getMatching() {
91
		return matching;
92
	}
93

  
94
	/* (non-Javadoc)
95
	 * @see eu.etaxonomy.cdm.strategy.match.IMatchStrategy#setMatchMode(java.lang.String, eu.etaxonomy.cdm.strategy.match.MatchMode)
96
	 */
97
	public void setMatchMode(String propertyName, MatchMode matchMode)
98
			throws MatchException {
99
		if (matchFields.containsKey(propertyName)){
100
			FieldMatcher fieldMatcher = FieldMatcher.NewInstance(matchFields.get(propertyName), matchMode);
101
			matching.setFieldMatcher(fieldMatcher);
102
		}else{
103
			throw new MatchException("The class " + matchClass.getName() + " does not contain a field named " + propertyName);
104
		}
105
	}
106
	
107
	/* (non-Javadoc)
108
	 * @see eu.etaxonomy.cdm.strategy.match.IMatchStrategy#getMatchMode(java.lang.String)
109
	 */
110
	public MatchMode getMatchMode(String propertyName) {
111
		FieldMatcher fieldMatcher = matching.getFieldMatcher(propertyName);
112
		return fieldMatcher == null ? defaultMatchMode : fieldMatcher.getMatchMode();
113
	}
114

  
115
	/* (non-Javadoc)
116
	 * @see eu.etaxonomy.cdm.strategy.match.IMatchStrategy#invoke(eu.etaxonomy.cdm.strategy.match.IMatchable, eu.etaxonomy.cdm.strategy.match.IMatchable)
117
	 */
118
	public <T extends IMatchable> boolean invoke(T matchFirst, T matchSecond)
119
			throws MatchException {
120
		boolean result = true;
121
		if (matchFirst == null || matchSecond == null){
122
			return false;
123
		}else if (matchFirst == matchSecond){
124
			return true;
125
		}else if (matchFirst.getClass() != matchSecond.getClass()){
126
			matchFirst = (T) HibernateProxyHelper.deproxy(matchFirst);
127
			matchSecond = (T) HibernateProxyHelper.deproxy(matchSecond);
128
			if (matchFirst.getClass() != matchSecond.getClass()){
129
				return false;
130
			}
131
		}
132
		matching.deleteTemporaryMatchers(); //just in case they are not yet deleted during last invoke
133
		if (! matchClass.isAssignableFrom(matchFirst.getClass()) ){
134
			throw new MatchException("Match object are of different type than the match class (" + matchClass + ") this match strategy was created with");
135
		}else if (matchClass != matchFirst.getClass()){
136
			initializeSubclass(matchFirst.getClass());
137
		}
138
		try {
139
			result = invokeChecked(matchFirst, matchSecond, result);
140
		}catch (MatchException e) {
141
			throw e;
142
		}finally{
143
			matching.deleteTemporaryMatchers();
144
		}
145
		return result;
146
	}
147

  
148
	/**
149
	 * @param class1
150
	 */
151
	private void initializeSubclass(Class<? extends IMatchable> instanceClass) {
152
		Map<String, Field> subClassFields = CdmUtils.getAllFields(instanceClass, matchClass, false, false, true, false);
153
		for (Field field: subClassFields.values()){
154
			initField(field, true);
155
		}
156
	}
157

  
158
	/**
159
	 * @param <T>
160
	 * @param matchFirst
161
	 * @param matchSecond
162
	 * @param result
163
	 * @return
164
	 * @throws MatchException
165
	 */
166
	private <T extends IMatchable> boolean invokeChecked(T matchFirst, T matchSecond,
167
			boolean result) throws MatchException {
168
		//matchFirst != matchSecond != null
169
		try {
170
			Map<String, List<MatchMode>> replaceMatchers = new HashMap<String, List<MatchMode>>();
171
			for (CacheMatcher cacheMatcher: matching.getCacheMatchers()){
172
				Field protectedField = cacheMatcher.getProtectedField(matching);
173
				boolean protected1 = protectedField.getBoolean(matchFirst);
174
				boolean protected2 = protectedField.getBoolean(matchFirst);
175
				if (protected1 != protected2){
176
					return false;
177
				}else if (protected1 == false){
178
					//ignore
179
				}else{
180
					String cache1 = (String)cacheMatcher.getField().get(matchFirst);
181
					String cache2 = (String)cacheMatcher.getField().get(matchSecond);
182
					result = cacheMatcher.getMatchMode().matches(cache1, cache2, null);
183
					if (result == false){
184
						return false;
185
					}
186
					List<DoubleResult<String, MatchMode>> replacementModes = cacheMatcher.getReplaceMatchModes(matching);
187
					for (DoubleResult<String, MatchMode> replacementMode: replacementModes ){
188
						String propertyName = replacementMode.getFirstResult();
189
						List<MatchMode> replaceMatcherList = replaceMatchers.get(propertyName);
190
						if (replaceMatcherList == null){
191
							replaceMatcherList = new ArrayList<MatchMode>();
192
							replaceMatchers.put(propertyName, replaceMatcherList);
193
						}
194
						replaceMatcherList.add(replacementMode.getSecondResult());
195
					}
196
				}
197
			}
198
			for (FieldMatcher fieldMatcher : matching.getFieldMatchers(true)){
199
				Field field = fieldMatcher.getField();
200
				List<MatchMode> replaceModeList = replaceMatchers.get(fieldMatcher.getPropertyName());
201
				if (replaceModeList == null){
202
					replaceModeList = new ArrayList<MatchMode>();
203
				}
204
				Class<?> fieldType = field.getType();
205
				logger.debug(field.getName() + ": ");
206
				if (isPrimitive(fieldType)){
207
					result &= matchPrimitiveField(matchFirst, matchSecond, fieldMatcher, replaceModeList);
208
				}else if (fieldType == String.class ){
209
					result &= matchPrimitiveField(matchFirst, matchSecond, fieldMatcher, replaceModeList);
210
				}else if (fieldType == Integer.class ){
211
					result &= matchPrimitiveField(matchFirst, matchSecond, fieldMatcher, replaceModeList);
212
				}else if(isUserType(fieldType)){
213
					result &= matchPrimitiveField(matchFirst, matchSecond, fieldMatcher, replaceModeList);
214
				}else if(fieldType == UUID.class){
215
					//result &= matchPrimitiveField(matchFirst, matchSecond, fieldMatcher, replaceModeList);
216
				}else if(fieldType == URI.class){
217
					result &= matchPrimitiveField(matchFirst, matchSecond, fieldMatcher, replaceModeList);
218
				}else if(fieldType == DOI.class){
219
					result &= matchPrimitiveField(matchFirst, matchSecond, fieldMatcher, replaceModeList);
220
				}else if(isSingleCdmBaseObject(fieldType)){
221
					result &= matchPrimitiveField(matchFirst, matchSecond, fieldMatcher, replaceModeList);
222
				}else if (isCollection(fieldType)){
223
					result &= matchCollectionField(matchFirst, matchSecond, fieldMatcher, replaceModeList);
224
				}else if(fieldType.isInterface()){
225
					result &= matchPrimitiveField(matchFirst, matchSecond, fieldMatcher, replaceModeList);
226
				}else if(fieldType.isEnum()){
227
					result &= matchPrimitiveField(matchFirst, matchSecond, fieldMatcher, replaceModeList);
228
				}else{
229
					throw new RuntimeException("Unknown Object type for matching: " + fieldType);
230
				}
231
//				if (result == false){
232
//					return result;
233
//				}
234
			}
235
		} catch (Exception e) {
236
			throw new MatchException("Match Exception in invoke", e);
237
		}
238
		return result;
239
	}
240

  
241
		
242
	/**
243
	 * @throws Exception 
244
	 * 
245
	 */
246
	private <T extends IMatchable> boolean matchPrimitiveField(T matchFirst, T matchSecond, FieldMatcher fieldMatcher, List<MatchMode> replaceModeList) throws Exception {
247
		Field field = fieldMatcher.getField();
248
		Object value1 = checkEmpty(field.get(matchFirst));
249
		Object value2 = checkEmpty(field.get(matchSecond));
250
		IMatchStrategy matchStrategy = fieldMatcher.getMatchStrategy();
251
		boolean result = fieldMatcher.getMatchMode().matches(value1, value2, matchStrategy);
252
		for (MatchMode replaceMode : replaceModeList){
253
			if (result == true){
254
				break; 
255
			}
256
			result |= replaceMode.matches(value1, value2, null);
257
		}
258
		logger.debug(fieldMatcher.getMatchMode() + ", " + field.getType().getName()+ ": " + result);
259
		return result;
260
	}
261

  
262
	/**
263
	 * @throws Exception 
264
	 * 
265
	 */
266
	private <T extends IMatchable> boolean matchCollectionField(T matchFirst, T matchSecond, FieldMatcher fieldMatcher, List<MatchMode> replaceModeList) throws Exception {
267
		boolean result;
268
		Field field = fieldMatcher.getField();
269
		Collection<?> value1 = (Collection)field.get(matchFirst);
270
		Collection<?> value2 = (Collection)field.get(matchSecond);
271
		MatchMode matchMode = fieldMatcher.getMatchMode();
272
		Class<?> fieldType = fieldMatcher.getField().getType();
273
		IMatchStrategy matchStrategy = fieldMatcher.getMatchStrategy();
274
		if (matchMode.isMatch()){
275
			Class collectionType = getTypeOfSet(field);
276
			if (! IMatchable.class.isAssignableFrom(collectionType)){
277
				//TODO
278
				return fieldMatcher.getMatchMode().matches(value1, value2, matchStrategy);	
279
			}
280
			if (matchStrategy == null){
281
				matchStrategy = DefaultMatchStrategy.NewInstance(collectionType);
282
			}
283
			if (Set.class.isAssignableFrom(fieldType)){
284
				result = matchSet(value1, value2, matchStrategy);
285
			}else if (List.class.isAssignableFrom(fieldType)){
286
				result = matchList(value1, value2, matchStrategy);
287
			}else{
288
				throw new MatchException("Collection type not yet supported: " + fieldType);
289
			}
290
		}else{
291
			result = fieldMatcher.getMatchMode().matches(value1, value2, matchStrategy);
292
		}
293
		//cache replace modes
294
		for (MatchMode replaceMode : replaceModeList){
295
			if (result == true){
296
				break; 
297
			}
298
			result |= replaceMode.matches(value1, value2, null);
299
		}
300
		logger.debug(fieldMatcher.getMatchMode() + ", " + field.getType().getName()+ ": " + result);
301
		return result;
302
	}
303

  
304

  
305
	/**
306
	 * @param object
307
	 * @return
308
	 */
309
	private Object checkEmpty(Object object) {
310
		if (object instanceof String){
311
			if (StringUtils.isBlank((String)object)){
312
				return null;
313
			}
314
		}
315
		return HibernateProxyHelper.deproxy(object);
316
	}
317

  
318
	/**
319
	 * @param value1
320
	 * @param matchStrategy
321
	 * @return
322
	 * @throws MatchException
323
	 */
324
	private boolean matchSet(Collection value1, Collection value2, IMatchStrategy matchStrategy)
325
			throws MatchException {
326
		boolean result;
327
		Set<IMatchable> set1 = (Set<IMatchable>)value1;
328
		Set<IMatchable> set2 = (Set<IMatchable>)value2;
329
		if (set1.size()!= set2.size()){
330
			return false;
331
		}
332
		result = true;
333
		for (IMatchable setItem1: set1){
334
			boolean matches = false;
335
			for (IMatchable setItem2: set2){
336
				matches |= matchStrategy.invoke(setItem1, setItem2);
337
			}
338
			if (matches == false){
339
				return false;
340
			}
341
		}
342
		return result;
343
	}
344
	
345
	/**
346
	 * @param value1
347
	 * @param matchStrategy
348
	 * @return
349
	 * @throws MatchException
350
	 */
351
	private boolean matchList(Collection value1, Collection value2, IMatchStrategy matchStrategy)
352
			throws MatchException {
353
		boolean result;
354
		List<IMatchable> list1 = (List<IMatchable>)value1;
355
		List<IMatchable> list2 = (List<IMatchable>)value2;
356
		if(list1 == null && list2 == null) {
357
			return true;
358
		}
359
		
360
		if ((list1 != null && list2 == null) || (list1 == null && list2 != null) || (list1.size()!= list2.size())){
361
			return false;
362
		}
363
		
364
		result = true;
365
		for (int i = 0; i < list1.size(); i++){
366
			IMatchable listObject1 = list1.get(i);
367
			IMatchable listObject2 = list2.get(i);
368
			if (! matchStrategy.invoke(listObject1, listObject2)){
369
				return false;
370
			}
371
		}
372
		return result;
373
	}
374
	
375
	private Class<?> getTypeOfSet(Field field) throws MatchException{
376
		Type genericType = (ParameterizedType)field.getGenericType();
377
		if (genericType instanceof ParameterizedType/*Impl*/){
378
			ParameterizedType paraType = (ParameterizedType)genericType;
379
			paraType.getRawType();
380
			Type[] arguments = paraType.getActualTypeArguments();
381
			if (arguments.length == 1){
382
				Class<?> collectionClass;
383
				try {
384
					if (arguments[0] instanceof Class){
385
						return (Class)arguments[0];
386
					}else if(arguments[0] instanceof TypeVariable/*Impl*/){
387
						TypeVariable typeVariable = (TypeVariable)arguments[0];
388
						GenericDeclaration genericDeclaration = typeVariable.getGenericDeclaration();
389
						return (Class)genericDeclaration;
390
					}else{
391
						logger.warn("Unknown Type");
392
						throw new MatchException("");
393
					}
394
				} catch (Exception e) {
395
					logger.warn(e.getMessage());
396
					throw new MatchException("");
397
				}
398
			}else{
399
				logger.warn("Length of arguments <> 1");
400
				throw new MatchException("");
401
			}
402
		}else{
403
			logger.warn("Not a generic type of type ParameterizedTypeImpl");
404
			throw new MatchException("Collection type could not be determined. Generic type is not of type ParamterizedTypeImpl");
405
		}
406
	}
407
	
408
	
409
	/**
410
	 * 
411
	 */
412
	private void initMapping() {
413
		boolean includeStatic = false;
414
		boolean includeTransient = false;
415
		boolean makeAccessible = true;
416
		matchFields = CdmUtils.getAllFields(matchClass, CdmBase.class, includeStatic, includeTransient, makeAccessible, true);
417
		for (Field field: matchFields.values()){
418
			initField(field, false);
419
		}
420
	}
421

  
422
	/**
423
	 * Initializes the matching for a single field
424
	 * @param field
425
	 */
426
	private void initField(Field field, boolean temporary) {
427
		MatchMode matchMode = null;
428
		IMatchStrategy matchStrategy = null;
429
		for (Annotation annotation : field.getAnnotations()){
430
			if (annotation.annotationType() == Match.class){
431
				Match match = ((Match)annotation);
432
				matchMode = match.value();
433
				if (matchMode == MatchMode.CACHE){
434
					ReplaceMode replaceMode = match.cacheReplaceMode();
435
					String[] cachePropertyReplaces = match.cacheReplacedProperties();
436
					MatchMode replaceMatchMode = match.replaceMatchMode();
437
					matching.addCacheMatcher(CacheMatcher.NewInstance(field, replaceMode, cachePropertyReplaces, replaceMatchMode));
438
					
439
				}else{
440
					matching.setFieldMatcher(FieldMatcher.NewInstance(field, matchMode), temporary);
441
				}
442
			}
443
		}
444
		Class fieldType = field.getType();
445
		if (matchMode == null){
446
			if (isCollection(fieldType)){
447
				matchMode = defaultCollectionMatchMode;
448
				matching.setFieldMatcher(FieldMatcher.NewInstance(field, matchMode), temporary);
449
			}else if (fieldType.isInterface()){
450
				//TODO could be handled more sophisticated
451
				matchMode = defaultMatchMatchMode;
452
				matching.setFieldMatcher(FieldMatcher.NewInstance(field, matchMode, matchStrategy), temporary);
453
			}else if (isSingleCdmBaseObject(fieldType)){
454
				if (IMatchable.class.isAssignableFrom(fieldType)){
455
					matchMode = defaultMatchMatchMode;
456
					if (matchStrategy == null){
457
						if (fieldType == this.matchClass){
458
							matchStrategy = this;
459
						}else{
460
							matchStrategy = DefaultMatchStrategy.NewInstance(fieldType);
461
						}
462
					}
463
					matching.setFieldMatcher(FieldMatcher.NewInstance(field, matchMode, matchStrategy), temporary);
464
				}else{
465
					matchMode = defaultMatchMode;
466
					matching.setFieldMatcher(FieldMatcher.NewInstance(field, matchMode), temporary);
467
				}
468
			}else{
469
				matchMode = defaultMatchMode;
470
				matching.setFieldMatcher(FieldMatcher.NewInstance(field, matchMode), temporary);
471
			}	
472
		}
473
	}
474

  
475

  
476
	@Override
477
	public Set<String> getMatchFieldPropertyNames() {
478
		return matchFields.keySet();
479
	}
480

  
481
	
482
}
1
// $Id$
2
/**
3
* Copyright (C) 2007 EDIT
4
* European Distributed Institute of Taxonomy
5
* http://www.e-taxonomy.eu
6
*
7
* The contents of this file are subject to the Mozilla Public License Version 1.1
8
* See LICENSE.TXT at the top of this package for the full license terms.
9
*/
10

  
11
package eu.etaxonomy.cdm.strategy.match;
12

  
13
import java.lang.annotation.Annotation;
14
import java.lang.reflect.Field;
15
import java.lang.reflect.GenericDeclaration;
16
import java.lang.reflect.ParameterizedType;
17
import java.lang.reflect.Type;
18
import java.lang.reflect.TypeVariable;
19
import java.net.URI;
20
import java.util.ArrayList;
21
import java.util.Collection;
22
import java.util.HashMap;
23
import java.util.List;
24
import java.util.Map;
25
import java.util.Set;
26
import java.util.UUID;
27

  
28
import org.apache.commons.lang.StringUtils;
29
import org.apache.log4j.Logger;
30

  
31
import eu.etaxonomy.cdm.common.CdmUtils;
32
import eu.etaxonomy.cdm.common.DOI;
33
import eu.etaxonomy.cdm.common.DoubleResult;
34
import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
35
import eu.etaxonomy.cdm.model.common.CdmBase;
36
import eu.etaxonomy.cdm.strategy.StrategyBase;
37
import eu.etaxonomy.cdm.strategy.match.Match.ReplaceMode;
38

  
39
/**
40
 * @author a.mueller
41
 * @created 06.08.2009
42
 * @version 1.0
43
 */
44
public class DefaultMatchStrategy extends StrategyBase implements IMatchStrategy {
45
	private static final long serialVersionUID = 5045874493910155162L;
46
	private static final Logger logger = Logger.getLogger(DefaultMatchStrategy.class);
47

  
48
	final static UUID uuid = UUID.fromString("69467b70-07ec-43a6-b779-3ec8d013837b");
49

  
50
	public static DefaultMatchStrategy NewInstance(Class<? extends IMatchable> matchClazz){
51
		return new DefaultMatchStrategy(matchClazz);
52
	}
53

  
54
//	protected Map<String, MatchMode> matchModeMap = new HashMap<String, MatchMode>();
55
	protected MatchMode defaultMatchMode = MatchMode.EQUAL;
56
	protected MatchMode defaultCollectionMatchMode = MatchMode.IGNORE;
57
	protected MatchMode defaultMatchMatchMode = MatchMode.MATCH;
58

  
59
	protected Class<? extends IMatchable> matchClass;
60
	protected Map<String, Field> matchFields;
61
	protected Matching matching = new Matching();
62

  
63
	protected DefaultMatchStrategy(Class<? extends IMatchable> matchClazz) {
64
		super();
65
		if (matchClazz == null){
66
			throw new IllegalArgumentException("Match class must not be null");
67
		}
68
		this.matchClass = matchClazz;
69
		initMapping();
70
	}
71

  
72
	/**
73
	 * @return the merge class
74
	 */
75
	@Override
76
    public Class<? extends IMatchable> getMatchClass() {
77
		return matchClass;
78
	}
79

  
80
	/* (non-Javadoc)
81
	 * @see eu.etaxonomy.cdm.strategy.StrategyBase#getUuid()
82
	 */
83
	@Override
84
	protected UUID getUuid() {
85
		return uuid;
86
	}
87

  
88
	/* (non-Javadoc)
89
	 * @see eu.etaxonomy.cdm.strategy.match.IMatchStrategy#getMatching()
90
	 */
91
	@Override
92
    public Matching getMatching() {
93
		return matching;
94
	}
95

  
96
	/* (non-Javadoc)
97
	 * @see eu.etaxonomy.cdm.strategy.match.IMatchStrategy#setMatchMode(java.lang.String, eu.etaxonomy.cdm.strategy.match.MatchMode)
98
	 */
99
	@Override
100
    public void setMatchMode(String propertyName, MatchMode matchMode)
101
			throws MatchException {
102
		if (matchFields.containsKey(propertyName)){
103
			FieldMatcher fieldMatcher = FieldMatcher.NewInstance(matchFields.get(propertyName), matchMode);
104
			matching.setFieldMatcher(fieldMatcher);
105
		}else{
106
			throw new MatchException("The class " + matchClass.getName() + " does not contain a field named " + propertyName);
107
		}
108
	}
109

  
110
	/* (non-Javadoc)
111
	 * @see eu.etaxonomy.cdm.strategy.match.IMatchStrategy#getMatchMode(java.lang.String)
112
	 */
113
	@Override
114
    public MatchMode getMatchMode(String propertyName) {
115
		FieldMatcher fieldMatcher = matching.getFieldMatcher(propertyName);
116
		return fieldMatcher == null ? defaultMatchMode : fieldMatcher.getMatchMode();
117
	}
118

  
119
	/* (non-Javadoc)
120
	 * @see eu.etaxonomy.cdm.strategy.match.IMatchStrategy#invoke(eu.etaxonomy.cdm.strategy.match.IMatchable, eu.etaxonomy.cdm.strategy.match.IMatchable)
121
	 */
122
	@Override
123
    public <T extends IMatchable> boolean invoke(T matchFirst, T matchSecond)
124
			throws MatchException {
125
		boolean result = true;
126
		if (matchFirst == null || matchSecond == null){
127
			return false;
128
		}else if (matchFirst == matchSecond){
129
			return true;
130
		}else if (matchFirst.getClass() != matchSecond.getClass()){
131
			matchFirst = HibernateProxyHelper.deproxy(matchFirst);
132
			matchSecond = HibernateProxyHelper.deproxy(matchSecond);
133
			if (matchFirst.getClass() != matchSecond.getClass()){
134
				return false;
135
			}
136
		}
137
		matching.deleteTemporaryMatchers(); //just in case they are not yet deleted during last invoke
138
		if (! matchClass.isAssignableFrom(matchFirst.getClass()) ){
139
			throw new MatchException("Match object are of different type than the match class (" + matchClass + ") this match strategy was created with");
140
		}else if (matchClass != matchFirst.getClass()){
141
			initializeSubclass(matchFirst.getClass());
142
		}
143
		try {
144
			result = invokeChecked(matchFirst, matchSecond, result);
145
		}catch (MatchException e) {
146
			throw e;
147
		}finally{
148
			matching.deleteTemporaryMatchers();
149
		}
150
		return result;
151
	}
152

  
153
	/**
154
	 * @param class1
155
	 */
156
	private void initializeSubclass(Class<? extends IMatchable> instanceClass) {
157
		Map<String, Field> subClassFields = CdmUtils.getAllFields(instanceClass, matchClass, false, false, true, false);
158
		for (Field field: subClassFields.values()){
159
			initField(field, true);
160
		}
161
	}
162

  
163
	/**
164
	 * @param <T>
165
	 * @param matchFirst
166
	 * @param matchSecond
167
	 * @param result
168
	 * @return
169
	 * @throws MatchException
170
	 */
171
	private <T extends IMatchable> boolean invokeChecked(T matchFirst, T matchSecond,
172
			boolean result) throws MatchException {
173
		//matchFirst != matchSecond != null
174
		try {
175
			Map<String, List<MatchMode>> replaceMatchers = new HashMap<String, List<MatchMode>>();
176
			for (CacheMatcher cacheMatcher: matching.getCacheMatchers()){
177
				Field protectedField = cacheMatcher.getProtectedField(matching);
178
				boolean protected1 = protectedField.getBoolean(matchFirst);
179
				boolean protected2 = protectedField.getBoolean(matchFirst);
180
				if (protected1 != protected2){
181
					return false;
182
				}else if (protected1 == false){
183
					//ignore
184
				}else{
185
					String cache1 = (String)cacheMatcher.getField().get(matchFirst);
186
					String cache2 = (String)cacheMatcher.getField().get(matchSecond);
187
					result = cacheMatcher.getMatchMode().matches(cache1, cache2, null);
188
					if (result == false){
189
						return false;
190
					}
191
					List<DoubleResult<String, MatchMode>> replacementModes = cacheMatcher.getReplaceMatchModes(matching);
192
					for (DoubleResult<String, MatchMode> replacementMode: replacementModes ){
193
						String propertyName = replacementMode.getFirstResult();
194
						List<MatchMode> replaceMatcherList = replaceMatchers.get(propertyName);
195
						if (replaceMatcherList == null){
196
							replaceMatcherList = new ArrayList<MatchMode>();
197
							replaceMatchers.put(propertyName, replaceMatcherList);
198
						}
199
						replaceMatcherList.add(replacementMode.getSecondResult());
200
					}
201
				}
202
			}
203
			for (FieldMatcher fieldMatcher : matching.getFieldMatchers(true)){
204
				Field field = fieldMatcher.getField();
205
				List<MatchMode> replaceModeList = replaceMatchers.get(fieldMatcher.getPropertyName());
206
				if (replaceModeList == null){
207
					replaceModeList = new ArrayList<MatchMode>();
208
				}
209
				Class<?> fieldType = field.getType();
210
				logger.debug(field.getName() + ": ");
211
				if (isPrimitive(fieldType)){
212
					result &= matchPrimitiveField(matchFirst, matchSecond, fieldMatcher, replaceModeList);
213
				}else if (fieldType == String.class ){
214
					result &= matchPrimitiveField(matchFirst, matchSecond, fieldMatcher, replaceModeList);
215
				}else if (fieldType == Integer.class ){
216
					result &= matchPrimitiveField(matchFirst, matchSecond, fieldMatcher, replaceModeList);
217
				}else if(isUserType(fieldType)){
218
					result &= matchPrimitiveField(matchFirst, matchSecond, fieldMatcher, replaceModeList);
219
				}else if(fieldType == UUID.class){
220
					//result &= matchPrimitiveField(matchFirst, matchSecond, fieldMatcher, replaceModeList);
221
				}else if(fieldType == URI.class){
222
					result &= matchPrimitiveField(matchFirst, matchSecond, fieldMatcher, replaceModeList);
223
				}else if(fieldType == DOI.class){
224
					result &= matchPrimitiveField(matchFirst, matchSecond, fieldMatcher, replaceModeList);
225
				}else if(isSingleCdmBaseObject(fieldType)){
226
					result &= matchPrimitiveField(matchFirst, matchSecond, fieldMatcher, replaceModeList);
227
				}else if (isCollection(fieldType)){
228
					result &= matchCollectionField(matchFirst, matchSecond, fieldMatcher, replaceModeList);
229
				}else if(fieldType.isInterface()){
230
					result &= matchPrimitiveField(matchFirst, matchSecond, fieldMatcher, replaceModeList);
231
				}else if(fieldType.isEnum()){
232
					result &= matchPrimitiveField(matchFirst, matchSecond, fieldMatcher, replaceModeList);
233
				}else{
234
					throw new RuntimeException("Unknown Object type for matching: " + fieldType);
235
				}
236
//				if (result == false){
237
//					return result;
238
//				}
239
			}
240
		} catch (Exception e) {
241
			throw new MatchException("Match Exception in invoke", e);
242
		}
243
		return result;
244
	}
245

  
246

  
247
	/**
248
	 * @throws Exception
249
	 *
250
	 */
251
	private <T extends IMatchable> boolean matchPrimitiveField(T matchFirst, T matchSecond, FieldMatcher fieldMatcher, List<MatchMode> replaceModeList) throws Exception {
252
		Field field = fieldMatcher.getField();
253
		Object value1 = checkEmpty(field.get(matchFirst));
254
		Object value2 = checkEmpty(field.get(matchSecond));
255
		IMatchStrategy matchStrategy = fieldMatcher.getMatchStrategy();
256
		boolean result = fieldMatcher.getMatchMode().matches(value1, value2, matchStrategy);
257
		for (MatchMode replaceMode : replaceModeList){
258
			if (result == true){
259
				break;
260
			}
261
			result |= replaceMode.matches(value1, value2, null);
262
		}
263
		logger.debug(fieldMatcher.getMatchMode() + ", " + field.getType().getName()+ ": " + result);
264
		return result;
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff