1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.syncope.core.persistence.jpa.content;
20
21 import java.io.IOException;
22 import java.io.InputStream;
23 import java.util.Properties;
24 import javax.sql.DataSource;
25 import javax.xml.XMLConstants;
26 import javax.xml.parsers.ParserConfigurationException;
27 import javax.xml.parsers.SAXParser;
28 import javax.xml.parsers.SAXParserFactory;
29 import org.apache.syncope.core.persistence.api.content.ContentLoader;
30 import org.apache.syncope.core.persistence.jpa.entity.JPARealm;
31 import org.apache.syncope.core.spring.ApplicationContextProvider;
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
34 import org.springframework.core.env.Environment;
35 import org.springframework.core.io.Resource;
36 import org.springframework.core.io.support.PropertiesLoaderUtils;
37 import org.springframework.dao.DataAccessException;
38 import org.springframework.jdbc.core.JdbcTemplate;
39 import org.springframework.orm.jpa.EntityManagerFactoryUtils;
40 import org.xml.sax.SAXException;
41
42
43
44
45 public class XMLContentLoader implements ContentLoader {
46
47 protected static final Logger LOG = LoggerFactory.getLogger(XMLContentLoader.class);
48
49 protected final Resource viewsXML;
50
51 protected final Resource indexesXML;
52
53 protected final Environment env;
54
55 public XMLContentLoader(
56 final Resource viewsXML,
57 final Resource indexesXML,
58 final Environment env) {
59
60 this.viewsXML = viewsXML;
61 this.indexesXML = indexesXML;
62 this.env = env;
63 }
64
65 @Override
66 public int getOrder() {
67 return 400;
68 }
69
70 @Override
71 public void load(final String domain, final DataSource datasource) {
72 LOG.debug("Loading data for domain [{}]", domain);
73
74
75 EntityManagerFactoryUtils.findEntityManagerFactory(
76 ApplicationContextProvider.getBeanFactory(), domain).createEntityManager();
77
78 JdbcTemplate jdbcTemplate = new JdbcTemplate(datasource);
79 boolean existingData;
80 try {
81 existingData = jdbcTemplate.queryForObject("SELECT COUNT(0) FROM " + JPARealm.TABLE, Integer.class) > 0;
82 } catch (DataAccessException e) {
83 LOG.error("[{}] Could not access table " + JPARealm.TABLE, domain, e);
84 existingData = true;
85 }
86
87 if (existingData) {
88 LOG.info("[{}] Data found in the database, leaving untouched", domain);
89 } else {
90 LOG.info("[{}] Empty database found, loading default content", domain);
91
92 try {
93 createViews(domain, datasource);
94 } catch (IOException e) {
95 LOG.error("[{}] While creating views", domain, e);
96 }
97 try {
98 createIndexes(domain, datasource);
99 } catch (IOException e) {
100 LOG.error("[{}] While creating indexes", domain, e);
101 }
102 try {
103 InputStream contentXML = ApplicationContextProvider.getBeanFactory().
104 getBean(domain + "ContentXML", InputStream.class);
105 loadDefaultContent(domain, contentXML, datasource);
106 } catch (Exception e) {
107 LOG.error("[{}] While loading default content", domain, e);
108 }
109 }
110 }
111
112 protected void loadDefaultContent(
113 final String domain, final InputStream contentXML, final DataSource dataSource)
114 throws IOException, ParserConfigurationException, SAXException {
115
116 SAXParserFactory factory = SAXParserFactory.newInstance();
117 factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, Boolean.TRUE);
118 factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
119 try (contentXML) {
120 SAXParser parser = factory.newSAXParser();
121 parser.parse(contentXML, new ContentLoaderHandler(dataSource, ROOT_ELEMENT, true, env));
122 LOG.debug("[{}] Default content successfully loaded", domain);
123 }
124 }
125
126 protected void createViews(final String domain, final DataSource dataSource) throws IOException {
127 LOG.debug("[{}] Creating views", domain);
128
129 JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
130
131 Properties views = PropertiesLoaderUtils.loadProperties(viewsXML);
132 views.stringPropertyNames().stream().sorted().forEach(idx -> {
133 LOG.debug("[{}] Creating view {}", domain, views.get(idx).toString());
134 try {
135 jdbcTemplate.execute(views.getProperty(idx).replaceAll("\\n", " "));
136 } catch (DataAccessException e) {
137 LOG.error("[{}] Could not create view", domain, e);
138 }
139 });
140
141 LOG.debug("Views created");
142 }
143
144 protected void createIndexes(final String domain, final DataSource dataSource) throws IOException {
145 LOG.debug("[{}] Creating indexes", domain);
146
147 JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
148
149 Properties indexes = PropertiesLoaderUtils.loadProperties(indexesXML);
150 indexes.stringPropertyNames().stream().sorted().forEach(idx -> {
151 LOG.debug("[{}] Creating index {}", domain, indexes.get(idx).toString());
152 try {
153 jdbcTemplate.execute(indexes.getProperty(idx));
154 } catch (DataAccessException e) {
155 LOG.error("[{}] Could not create index", domain, e);
156 }
157 });
158
159 LOG.debug("Indexes created");
160 }
161 }