Project

General

Profile

Download (7.85 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.URISyntaxException;
19
import java.net.URL;
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.SessionFactory;
27
import org.hibernate.boot.Metadata;
28
import org.hibernate.boot.MetadataSources;
29
import org.hibernate.boot.registry.StandardServiceRegistry;
30
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
31
import org.hibernate.cfg.Configuration;
32
import org.hibernate.mapping.PersistentClass;
33
import org.hibernate.mapping.Property;
34
import org.hibernate.metadata.ClassMetadata;
35
import org.hibernate.property.access.spi.Getter;
36

    
37
import net.sf.ehcache.Cache;
38
import net.sf.ehcache.Element;
39

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

    
50
    private static final Logger logger = LogManager.getLogger(CdmModelCacher.class);
51

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

    
54
    public static final String CDM_MAP_SER_FILE = "cdm.map.ser";
55
    public static final String CDM_MAP_SER_FOLDER = "/eu/etaxonomy/cdm/mappings/";
56
    public static final String CDM_MAP_SER_FILE_PATH = CDM_MAP_SER_FOLDER + CDM_MAP_SER_FILE;
57

    
58
    public void cacheGetterFields(Cache cache) throws IOException, ClassNotFoundException, URISyntaxException {
59
        Map<String, CdmModelFieldPropertyFromClass> modelClassMap = loadModelClassMap();
60

    
61
        cache.removeAll();
62

    
63
        for(Map.Entry<String, CdmModelFieldPropertyFromClass> entry : modelClassMap.entrySet()) {
64
            cache.put(new Element(entry.getKey(), entry.getValue()));
65
        }
66
    }
67

    
68
    public Map<String, CdmModelFieldPropertyFromClass> loadModelClassMap() throws URISyntaxException, IOException, ClassNotFoundException  {
69

    
70
        // ============== Eclpipse specific ============== //
71
        /*Bundle bundle = Platform.getBundle("eu.etaxonomy.taxeditor.cdmlib");
72

    
73
        URL modelMapFileBundleURL = bundle.getEntry(CDM_MAP_SER_FILE_PATH);
74
        URL modelMapFileURL = FileLocator.resolve(modelMapFileBundleURL);
75
        String modelMapFilePath = modelMapFileURL.getFile();
76
        FileInputStream fin = new FileInputStream(modelMapFilePath);
77
        */
78
        InputStream fin = this.getClass().getResourceAsStream(CDM_MAP_SER_FILE_PATH);
79
        // ==============000000000000000 ============== //
80

    
81
        ObjectInputStream ois = new ObjectInputStream(fin);
82
        @SuppressWarnings("unchecked")
83
		Map<String, CdmModelFieldPropertyFromClass> modelClassMap = (Map<String, CdmModelFieldPropertyFromClass>) ois.readObject();
84
        ois.close();
85
        return modelClassMap;
86
    }
87

    
88
    public Map<String, CdmModelFieldPropertyFromClass> generateModelClassMap() {
89

    
90
    	// A SessionFactory is set up once for an application!
91
        URL hibernateConfigFile = this.getClass().getResource(HB_CONFIG_FILE_PATH);
92
    	final StandardServiceRegistry registry = new StandardServiceRegistryBuilder()
93
    			.configure(hibernateConfigFile) // configures settings from hibernate.cfg.xml
94
    			.build();
95
    	SessionFactory sessionFactory = null;
96
    	Map<String, CdmModelFieldPropertyFromClass> modelClassMap = new HashMap<>();
97
    	try {
98
//    		ConnectionProvider connectionProvider = registry.getService(ConnectionProvider.class);
99
//    		DatasourceConnectionProviderImpl providerImpl = registry.getService(DatasourceConnectionProviderImpl.class);
100

    
101
    		Metadata metadata = new MetadataSources( registry ).buildMetadata();
102
    		sessionFactory = metadata.buildSessionFactory();
103
//    		Configuration configuration = buildConfiguration(HB_CONFIG_FILE_PATH);
104
        	Map<String, ClassMetadata> classMetaDataMap = sessionFactory.getAllClassMetadata();
105
//        	Metadata metadata = new MetadataSources( registry ).getMetadataBuilder().applyImplicitNamingStrategy( ImplicitNamingStrategyJpaCompliantImpl.INSTANCE ).build();
106

    
107
            for(ClassMetadata classMetaData : classMetaDataMap.values()) {
108
            	Class<?> mappedClass = classMetaData.getMappedClass();
109

    
110
                String mappedClassName = mappedClass.getName();
111

    
112
                PersistentClass persistentClass = metadata.getEntityBinding(mappedClassName);
113
                CdmModelFieldPropertyFromClass cmgmfc = new CdmModelFieldPropertyFromClass(mappedClassName);
114
                logger.warn("Adding class : " + mappedClassName + " to cache");
115
                addGetters(persistentClass, cmgmfc);
116
                modelClassMap.put(mappedClassName, cmgmfc);
117
            }
118
    	}
119
    	catch (Exception e) {
120
    		// The registry would be destroyed by the SessionFactory, but we had trouble building the SessionFactory
121
    		// so destroy it manually.
122
    		StandardServiceRegistryBuilder.destroy( registry );
123
    		e.printStackTrace();
124
    	}
125
        return modelClassMap;
126
    }
127

    
128
    public static Configuration buildConfiguration(String hibernateConfigFilePath) {
129
        Configuration configuration = new Configuration().configure(hibernateConfigFilePath);
130
        configuration.buildMappings();
131
        return configuration;
132
    }
133

    
134
    private void addGetters(PersistentClass persistentClass, CdmModelFieldPropertyFromClass cmgmfc) {
135
        if (persistentClass != null) {
136
            @SuppressWarnings("unchecked")
137
            Iterator<Property> propertyIt = persistentClass.getPropertyIterator();
138

    
139
            while(propertyIt.hasNext()){
140
                Property property = propertyIt.next();
141
                Getter getter = property.getGetter(persistentClass.getMappedClass());
142
                if(getter != null && getter.getMember() != null) {
143
                    Field field = (Field)getter.getMember();
144

    
145
                    //logger.info(" - contains field '" + field.getName() + "' of type '" + field.getType().getName() + "'");
146
                    cmgmfc.addGetMethods(field.getName());
147
                }
148
            }
149
            addGetters(persistentClass.getSuperclass(), cmgmfc);
150
        }
151
    }
152

    
153
    public static void main(String argv[]) {
154

    
155
        // To re-create the serialised cdm map run,
156
        // mvn exec:java -Dexec.mainClass="eu.etaxonomy.cdm.cache.CdmModelCacher"
157
        // in the eu.etaxonomy.taxeditor.cdmlib project root dir
158
    	// See also https://dev.e-taxonomy.eu/redmine/projects/edit/wiki/TaxonomicEditorDevelopersGuide#Model-Change-Actions
159
    	//Note AM: does not fully work for me, but running the main from the IDE works.
160

    
161
        CdmModelCacher cdmModelCacher = new CdmModelCacher();
162
        Map<String, CdmModelFieldPropertyFromClass> modelClassMap = cdmModelCacher.generateModelClassMap();
163
        try{
164
        	if (!modelClassMap.isEmpty()){
165
        	    File outFile = new File("src/main/resources/" + CDM_MAP_SER_FILE_PATH);
166
        	    System.out.println("writing to " + outFile.getAbsolutePath());
167
        		FileOutputStream fout = new FileOutputStream(outFile);
168
        		ObjectOutputStream oos = new ObjectOutputStream(fout);
169
        		oos.writeObject(modelClassMap);
170
        		oos.close();
171
        		System.out.println("CDM Map serialized");
172
        	}else{
173
        		String message = "CDM Map was empty. Model cache update NOT successful";
174
        		System.out.println(message);
175
        	}
176

    
177
        }catch(Exception ex){
178
            ex.printStackTrace();
179
        }
180
    }
181
}
(4-4/12)