1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.about.app;
35
36 import info.magnolia.cms.beans.config.ServerConfiguration;
37 import info.magnolia.cms.license.LicenseFileExtractor;
38 import info.magnolia.context.MgnlContext;
39 import info.magnolia.i18nsystem.SimpleTranslator;
40 import info.magnolia.init.MagnoliaConfigurationProperties;
41
42 import java.io.File;
43 import java.sql.Connection;
44 import java.sql.DatabaseMetaData;
45 import java.sql.DriverManager;
46 import java.sql.PreparedStatement;
47 import java.sql.ResultSet;
48 import java.sql.SQLException;
49
50 import javax.inject.Inject;
51 import javax.jcr.Repository;
52 import javax.jcr.RepositoryException;
53 import javax.xml.parsers.SAXParserFactory;
54
55 import org.apache.commons.lang3.StringUtils;
56 import org.apache.jackrabbit.commons.JcrUtils;
57 import org.slf4j.Logger;
58 import org.slf4j.LoggerFactory;
59 import org.xml.sax.Attributes;
60 import org.xml.sax.SAXException;
61 import org.xml.sax.helpers.DefaultHandler;
62
63 import com.vaadin.data.Item;
64 import com.vaadin.data.util.ObjectProperty;
65 import com.vaadin.data.util.PropertysetItem;
66
67
68
69
70 public class AboutPresenter {
71
72 private static final Logger log = LoggerFactory.getLogger(AboutPresenter.class);
73
74 private final AboutView view;
75
76 private final ServerConfiguration serverConfiguration;
77 private final MagnoliaConfigurationProperties magnoliaProperties;
78
79 protected final SimpleTranslator i18n;
80
81
82 protected Item viewData = new PropertysetItem();
83
84 @Inject
85 public AboutPresenter(AboutView view, ServerConfiguration serverConfiguration, MagnoliaConfigurationProperties magnoliaProperties, SimpleTranslator i18n) {
86 this.view = view;
87 this.serverConfiguration = serverConfiguration;
88 this.magnoliaProperties = magnoliaProperties;
89 this.i18n = i18n;
90 }
91
92 public AboutView start() {
93
94
95 LicenseFileExtractor licenseProperties = LicenseFileExtractor.getInstance();
96 String mgnlEdition = getEditionName();
97 String mgnlVersion = licenseProperties.get(LicenseFileExtractor.VERSION_NUMBER);
98 String authorInstance = serverConfiguration.isAdmin() ?
99 i18n.translate("about.app.main.instance.author") :
100 i18n.translate("about.app.main.instance.public");
101
102
103 String osInfo = String.format("%s %s (%s)",
104 magnoliaProperties.getProperty("os.name"),
105 magnoliaProperties.getProperty("os.version"),
106 magnoliaProperties.getProperty("os.arch"));
107 String javaInfo = String.format("%s (build %s)",
108 magnoliaProperties.getProperty("java.version"),
109 magnoliaProperties.getProperty("java.runtime.version"));
110 String serverInfo = MgnlContext.getWebContext().getServletContext().getServerInfo();
111
112 String dbInfo;
113 String dbDriverInfo;
114 Connection connection = null;
115 try {
116
117 String connectionString[] = getConnectionString();
118
119 String repoHome = magnoliaProperties.getProperty("magnolia.repositories.home");
120 String repoName = getRepoName();
121 connectionString[0] = StringUtils.replace(connectionString[0], "${wsp.home}", repoHome + "/" + repoName + "/workspaces/default");
122 connection = DriverManager.getConnection(connectionString[0], connectionString[1], connectionString[2]);
123 DatabaseMetaData meta = connection.getMetaData();
124 dbInfo = meta.getDatabaseProductName() + " " + meta.getDatabaseProductVersion();
125 if (dbInfo.toLowerCase().indexOf("mysql") != -1) {
126 String engine = getMySQLEngineInfo(connection, connectionString);
127 if (engine != null) {
128 dbInfo += engine;
129 }
130 }
131 dbDriverInfo = meta.getDriverName() + " " + meta.getDriverVersion();
132
133 } catch (SQLException e) {
134 log.debug("Failed to read DB and driver info from connection with {}", e.getMessage(), e);
135 dbInfo = i18n.translate("about.app.main.unknown");
136 dbDriverInfo = dbInfo;
137 } finally {
138 if (connection != null) {
139 try {
140 connection.close();
141 } catch (SQLException e) {
142
143 }
144 }
145 }
146
147 String jcrInfo;
148 try {
149 Repository repo = JcrUtils.getRepository();
150 jcrInfo = String.format("%s %s",
151 repo.getDescriptor("jcr.repository.name"),
152 repo.getDescriptor("jcr.repository.version"));
153 } catch (RepositoryException e) {
154 log.debug("JCR repository information is not available", e);
155 jcrInfo = "-";
156 }
157
158
159 viewData.addItemProperty(AboutView.MAGNOLIA_EDITION_KEY, new ObjectProperty<String>(mgnlEdition));
160 viewData.addItemProperty(AboutView.MAGNOLIA_VERSION_KEY, new ObjectProperty<String>(mgnlVersion));
161 viewData.addItemProperty(AboutView.MAGNOLIA_INSTANCE_KEY, new ObjectProperty<String>(authorInstance));
162 viewData.addItemProperty(AboutView.OS_INFO_KEY, new ObjectProperty<String>(osInfo));
163 viewData.addItemProperty(AboutView.JAVA_INFO_KEY, new ObjectProperty<String>(javaInfo));
164 viewData.addItemProperty(AboutView.SERVER_INFO_KEY, new ObjectProperty<String>(serverInfo));
165 viewData.addItemProperty(AboutView.JCR_INFO_KEY, new ObjectProperty<String>(jcrInfo));
166 viewData.addItemProperty(AboutView.DB_INFO_KEY, new ObjectProperty<String>(dbInfo));
167 viewData.addItemProperty(AboutView.DB_DRIVER_INFO_KEY, new ObjectProperty<String>(dbDriverInfo));
168 view.setDataSource(viewData);
169
170 return view;
171 }
172
173
174
175
176 protected String getEditionName() {
177
178 return i18n.translate("about.app.main.communityEdition");
179 }
180
181 private String getMySQLEngineInfo(Connection connection, String[] connectionString) {
182 PreparedStatement statement = null;
183 ResultSet resultSet = null;
184 try {
185 statement = connection.prepareStatement("SHOW TABLE STATUS FROM `" + StringUtils.substringAfterLast(connectionString[0], "/") + "`;");
186 resultSet = statement.executeQuery();
187 if (resultSet.next()) {
188 String engine = resultSet.getString("Engine");
189 return " (" + engine + ")";
190 }
191 } catch (SQLException e) {
192
193 } finally {
194 try {
195 if (resultSet != null) {
196 resultSet.close();
197 }
198 if (statement != null) {
199 statement.close();
200 }
201 } catch (SQLException e) {
202 }
203 }
204 return null;
205 }
206
207 String[] getConnectionString() {
208 File config = null;
209
210
211 String configuredPath = magnoliaProperties.getProperty("magnolia.repositories.jackrabbit.config");
212 if(configuredPath!=null){
213 if(configuredPath.startsWith("WEB-INF")){
214 config = new File(magnoliaProperties.getProperty("magnolia.app.rootdir") + "/" +configuredPath);
215 }else {
216 config = new File(configuredPath);
217 }
218 }
219
220
221
222 final String[] connectionString = new String[3];
223 try {
224 SAXParserFactory.newInstance().newSAXParser().parse(config, new DefaultHandler() {
225 private boolean inPM;
226
227 @Override
228 public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
229 super.startElement(uri, localName, qName, attributes);
230 if ("PersistenceManager".equals(qName) || "DataSource".equals(qName)) {
231 inPM = true;
232 }
233 if (inPM && "param".equals(qName)) {
234 if ("url".equals(attributes.getValue("name"))) {
235 connectionString[0] = attributes.getValue("value");
236 }
237 if ("user".equals(attributes.getValue("name"))) {
238 connectionString[1] = attributes.getValue("value");
239 }
240 if ("password".equals(attributes.getValue("name"))) {
241 connectionString[2] = attributes.getValue("value");
242 }
243 }
244 }
245
246 @Override
247 public void endElement(String uri, String localName, String qName) throws SAXException {
248 super.endElement(uri, localName, qName);
249 if ("PersistenceManager".equals(localName) || "DataSource".equals(qName)) {
250 inPM = false;
251 }
252 }
253 });
254 return connectionString;
255 } catch (Exception e) {
256 log.debug("Failed to obtain DB connection info with {}", e.getMessage(), e);
257 }
258 return null;
259 }
260
261 String getRepoName() {
262 String repoConfigPath = magnoliaProperties.getProperty("magnolia.repositories.config");
263 File config = new File(magnoliaProperties.getProperty("magnolia.app.rootdir") + "/" + repoConfigPath);
264 final String[] repoName = new String[1];
265 try {
266 SAXParserFactory.newInstance().newSAXParser().parse(config, new DefaultHandler() {
267 private boolean inRepo;
268
269 @Override
270 public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
271 super.startElement(uri, localName, qName, attributes);
272 if ("RepositoryMapping".equals(qName)) {
273 inRepo = true;
274 }
275 if (inRepo && "Map".equals(qName)) {
276 if ("config".equals(attributes.getValue("name"))) {
277 repoName[0] = attributes.getValue("repositoryName");
278 }
279 }
280 }
281
282 @Override
283 public void endElement(String uri, String localName, String qName) throws SAXException {
284 super.endElement(uri, localName, qName);
285 if ("RepositoryMapping".equals(localName)) {
286 inRepo = false;
287 }
288 }
289 });
290 return repoName[0];
291 } catch (Exception e) {
292 log.debug("Failed to obtain repository configuration info with {}", e.getMessage(), e);
293 }
294 return null;
295 }
296 }