Project

General

Profile

Download (7.21 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
 * Copyright (C) 2015 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.cache;
10

    
11
import java.io.File;
12
import java.io.FileOutputStream;
13
import java.io.IOException;
14
import java.io.InputStream;
15
import java.io.ObjectInputStream;
16
import java.io.ObjectOutputStream;
17
import java.lang.reflect.Field;
18
import java.net.URL;
19
import java.util.Collection;
20
import java.util.HashMap;
21
import java.util.Iterator;
22
import java.util.Map;
23

    
24
import org.apache.logging.log4j.LogManager;
25
import org.apache.logging.log4j.Logger;
26
import org.hibernate.boot.Metadata;
27
import org.hibernate.boot.MetadataSources;
28
import org.hibernate.boot.registry.StandardServiceRegistry;
29
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
30
import org.hibernate.cfg.Configuration;
31
import org.hibernate.mapping.PersistentClass;
32
import org.hibernate.mapping.Property;
33
import org.hibernate.property.access.spi.Getter;
34

    
35
import net.sf.ehcache.Cache;
36

    
37
/**
38
 * This class is serializing and deserializing the CDM model for performance purposes.
39
 * To serialize see comments on {@link #main(String[])} and on
40
 * https://dev.e-taxonomy.eu/redmine/projects/edit/wiki/TaxonomicEditorDevelopersGuide#Model-Change-Actions
41
 *
42
 * @author c.mathew
43
 * @since 2015
44
 */
45
public class CdmModelCacher {
46

    
47
    private static final Logger logger = LogManager.getLogger(CdmModelCacher.class);
48

    
49
    public static String HB_CONFIG_FILE_PATH= "/eu/etaxonomy/cdm/mappings/hibernate.cfg.xml";
50

    
51
    public static final String CDM_MAP_SER_FILE = "cdm.map.ser";
52
    public static final String CDM_MAP_SER_FOLDER = "/eu/etaxonomy/cdm/mappings/";
53
    public static final String CDM_MAP_SER_FILE_PATH = CDM_MAP_SER_FOLDER + CDM_MAP_SER_FILE;
54

    
55
    public void cacheGetterFields(Cache cache) throws IOException, ClassNotFoundException {
56
        Map<String, CdmModelFieldPropertyFromClass> modelClassMap = loadModelClassMap();
57

    
58
        cache.removeAll();
59

    
60
        for(Map.Entry<String, CdmModelFieldPropertyFromClass> entry : modelClassMap.entrySet()) {
61
            cache.put(new net.sf.ehcache.Element(entry.getKey(), entry.getValue()));
62
        }
63
    }
64

    
65
    public Map<String, CdmModelFieldPropertyFromClass> loadModelClassMap() throws IOException, ClassNotFoundException  {
66

    
67
        InputStream fin = this.getClass().getResourceAsStream(CDM_MAP_SER_FILE_PATH);
68
        ObjectInputStream ois = new ObjectInputStream(fin);
69
        @SuppressWarnings("unchecked")
70
		Map<String, CdmModelFieldPropertyFromClass> modelClassMap = (Map<String, CdmModelFieldPropertyFromClass>) ois.readObject();
71
        ois.close();
72
        return modelClassMap;
73
    }
74

    
75
    public Map<String, CdmModelFieldPropertyFromClass> generateModelClassMap() {
76

    
77
    	// A SessionFactory is set up once for an application!
78
        URL hibernateConfigFile = this.getClass().getResource(HB_CONFIG_FILE_PATH);
79
    	final StandardServiceRegistry registry = new StandardServiceRegistryBuilder()
80
    			.configure(hibernateConfigFile) // configures settings from hibernate.cfg.xml
81
    			.build();
82

    
83
    	Map<String, CdmModelFieldPropertyFromClass> modelClassMap = new HashMap<>();
84
    	try {
85
//    		ConnectionProvider connectionProvider = registry.getService(ConnectionProvider.class);
86
//    		DatasourceConnectionProviderImpl providerImpl = registry.getService(DatasourceConnectionProviderImpl.class);
87

    
88
    		Metadata metadata = new MetadataSources( registry ).buildMetadata();
89
    		Collection<PersistentClass> entityBindings = metadata.getEntityBindings();
90
    		for (PersistentClass persistentClass : entityBindings) {
91
                Class<?> mappedClass = persistentClass.getMappedClass();
92
                if (mappedClass != null) {
93
                    handleEntityClass(modelClassMap, metadata, mappedClass);
94
                }
95
            }
96
    	}
97
    	catch (Exception e) {
98
    		StandardServiceRegistryBuilder.destroy( registry );
99
    		e.printStackTrace();
100
    	}
101
        return modelClassMap;
102
    }
103

    
104
    private void handleEntityClass(Map<String, CdmModelFieldPropertyFromClass> modelClassMap, Metadata metadata,
105
            Class<?> mappedClass) {
106
        String mappedClassName = mappedClass.getName();
107
        PersistentClass persistentClass = metadata.getEntityBinding(mappedClassName);
108
        CdmModelFieldPropertyFromClass fieldProperties = new CdmModelFieldPropertyFromClass(mappedClassName);
109
        logger.warn("Adding class : " + mappedClassName + " to cache");
110
        addGetters(persistentClass, fieldProperties);
111
        modelClassMap.put(mappedClassName, fieldProperties);
112
    }
113

    
114
    public static Configuration buildConfiguration(String hibernateConfigFilePath) {
115
        Configuration configuration = new Configuration().configure(hibernateConfigFilePath);
116
        return configuration;
117
    }
118

    
119
    private void addGetters(PersistentClass persistentClass, CdmModelFieldPropertyFromClass cmgmfc) {
120
        if (persistentClass != null) {
121
            @SuppressWarnings("unchecked")
122
            Iterator<Property> propertyIt = persistentClass.getPropertyIterator();
123

    
124
            while(propertyIt.hasNext()){
125
                Property property = propertyIt.next();
126
                Getter getter = property.getGetter(persistentClass.getMappedClass());
127
                if(getter != null && getter.getMember() != null) {
128
                    Field field = (Field)getter.getMember();
129

    
130
                    //logger.info(" - contains field '" + field.getName() + "' of type '" + field.getType().getName() + "'");
131
                    cmgmfc.addGetMethods(field.getName());
132
                }
133
            }
134
            addGetters(persistentClass.getSuperclass(), cmgmfc);
135
        }
136
    }
137

    
138
    public static void main(String argv[]) {
139

    
140
        // To create the serialised cdm map run
141
        // mvn exec:exec -Dexec.mainClass="eu.etaxonomy.cdm.cache.CdmModelCacher"
142
        // in the cdmlib-cache project root directory
143
    	// See also https://dev.e-taxonomy.eu/redmine/projects/edit/wiki/TaxonomicEditorDevelopersGuide#Model-Change-Actions
144
    	//Note AM: does not fully work for me, but running the main from the IDE works.
145

    
146
        System.out.println("Start CdmModelCacher main.");
147
        CdmModelCacher cdmModelCacher = new CdmModelCacher();
148
        Map<String, CdmModelFieldPropertyFromClass> modelClassMap = cdmModelCacher.generateModelClassMap();
149
        try{
150
            System.out.println("Model created.");
151
        	if (!modelClassMap.isEmpty()){
152
        	    String strPath = CdmModelCacher.class.getProtectionDomain().getCodeSource().getLocation().getFile();
153
                File outFile = new File(strPath + CDM_MAP_SER_FILE_PATH);
154

    
155
                System.out.println("writing to " + outFile.getAbsolutePath());
156
        		FileOutputStream fout = new FileOutputStream(outFile);
157
        		ObjectOutputStream oos = new ObjectOutputStream(fout);
158
        		oos.writeObject(modelClassMap);
159
        		oos.close();
160
        		System.out.println("CDM Map serialized");
161
                System.exit(0);
162
        	}else{
163
        		String message = "CDM Map was empty. Model cache update NOT successful";
164
        		System.out.println(message);
165
        	}
166
        }catch(Exception ex){
167
            ex.printStackTrace();
168
        }
169

    
170
        System.exit(1);
171
    }
172
}
(4-4/12)