001: /*
002: * Copyright 2006 Pentaho Corporation. All rights reserved.
003: * This software was developed by Pentaho Corporation and is provided under the terms
004: * of the Mozilla Public License, Version 1.1, or any later version. You may not use
005: * this file except in compliance with the license. If you need a copy of the license,
006: * please go to http://www.mozilla.org/MPL/MPL-1.1.txt. The Original Code is the Pentaho
007: * BI Platform. The Initial Developer is Pentaho Corporation.
008: *
009: * Software distributed under the Mozilla Public License is distributed on an "AS IS"
010: * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. Please refer to
011: * the license for the specific language governing your rights and limitations.
012: *
013: * @created Apr 28, 2005
014: * @author James Dixon
015: */
016:
017: package org.pentaho.plugin.olap;
018:
019: import java.util.Properties;
020:
021: import mondrian.olap.Connection;
022: import mondrian.olap.Cube;
023: import mondrian.olap.Dimension;
024: import mondrian.olap.Hierarchy;
025: import mondrian.olap.Member;
026: import mondrian.olap.MondrianException;
027: import mondrian.olap.Schema;
028:
029: import org.apache.commons.logging.Log;
030: import org.apache.commons.logging.LogFactory;
031: import org.pentaho.commons.connection.IPentahoConnection;
032: import org.pentaho.core.system.PentahoSystem;
033: import org.pentaho.core.util.DatasourceHelper;
034: import org.pentaho.data.PentahoConnectionFactory;
035: import org.pentaho.data.connection.mdx.MDXConnection;
036: import org.pentaho.data.connection.sql.SQLConnection;
037: import org.pentaho.messages.Messages;
038: import org.pentaho.plugin.ComponentBase;
039: import org.pentaho.util.logging.Logger;
040:
041: /**
042: * @author James Dixon
043: *
044: * TODO To change the template for this generated type comment go to Window -
045: * Preferences - Java - Code Style - Code Templates
046: */
047: public class MondrianModelComponent extends ComponentBase {
048:
049: private static final long serialVersionUID = -718697500002076945L;
050:
051: public Log getLogger() {
052: return LogFactory.getLog(MondrianModelComponent.class);
053: }
054:
055: protected boolean validateSystemSettings() {
056: // This component does not have any system settings to validate
057: return true;
058: }
059:
060: public boolean init() {
061: // get the settings from the system configuration file
062: return true;
063:
064: }
065:
066: public boolean validateAction() {
067:
068: return true;
069:
070: }
071:
072: public boolean executeAction() {
073:
074: return true;
075: }
076:
077: public void done() {
078:
079: }
080:
081: public static String getInitialQuery(Properties properties,
082: String cubeName) throws Throwable {
083: MDXConnection mdxConnection = new MDXConnection(properties,
084: null);
085: Connection connection = mdxConnection.getConnection();
086: if (connection == null) {
087: Logger
088: .error(
089: "MondrianModelComponent", Messages.getErrorString("MondrianModel.ERROR_0001_INVALID_CONNECTION", properties.toString())); //$NON-NLS-1$ //$NON-NLS-2$
090: return null;
091: }
092:
093: try {
094: return getInitialQuery(connection, cubeName);
095: } catch (Throwable t) {
096: if (t instanceof MondrianException) {
097: // pull the cause out, otherwise it never gets logged
098: Throwable cause = ((MondrianException) t).getCause();
099: if (cause != null) {
100: throw cause;
101: } else {
102: throw t;
103: }
104: } else {
105: throw t;
106: }
107: }
108: }
109:
110: /**
111: * @param modelPath
112: * @param connectionString
113: * @param driver
114: * @param user
115: * @param password
116: * @param cubeName
117: * @return mdx string that represents the initial query
118: * @throws Throwable
119: * @deprecated
120: */
121: public static String getInitialQuery(String modelPath,
122: String connectionString, String driver, String user,
123: String password, String cubeName) throws Throwable {
124: return getInitialQuery(modelPath, connectionString, driver,
125: user, password, cubeName, null);
126: }
127:
128: /**
129: * @param modelPath
130: * @param connectionString
131: * @param driver
132: * @param user
133: * @param password
134: * @param cubeName
135: * @param roleName
136: * @return mdx string that represents the initial query
137: * @throws Throwable
138: * @deprecated
139: */
140: public static String getInitialQuery(String modelPath,
141: String connectionString, String driver, String user,
142: String password, String cubeName, String roleName)
143: throws Throwable {
144:
145: Properties properties = new Properties();
146:
147: // TODO support driver manager connections
148: if (!PentahoSystem.ignored) {
149: if (driver != null) {
150: properties.put("Driver", driver); //$NON-NLS-1$
151: }
152: if (user != null) {
153: properties.put("User", user); //$NON-NLS-1$
154: }
155: if (password != null) {
156: properties.put("Password", password); //$NON-NLS-1$
157: }
158: }
159:
160: if (modelPath.indexOf("http") == 0) { //$NON-NLS-1$
161: properties.put("Catalog", modelPath); //$NON-NLS-1$
162: } else {
163: if (modelPath.indexOf("http") == 0) { //$NON-NLS-1$
164: properties.put("Catalog", modelPath); //$NON-NLS-1$
165: } else {
166: if (!modelPath.startsWith("solution:")) { //$NON-NLS-1$
167: modelPath = "solution:" + modelPath; //$NON-NLS-1$
168: }
169: properties.put("Catalog", modelPath); //$NON-NLS-1$
170: }
171: }
172: properties.put("Provider", "mondrian"); //$NON-NLS-1$ //$NON-NLS-2$
173: properties.put("PoolNeeded", "false"); //$NON-NLS-1$//$NON-NLS-2$
174: properties.put("dataSource", connectionString); //$NON-NLS-1$
175: if (roleName != null) {
176: properties.put("Role", roleName); //$NON-NLS-1$
177: }
178:
179: return getInitialQuery(properties, cubeName);
180: }
181:
182: /**
183: * @param modelPath
184: * @param connectionString
185: * @param cubeName
186: * @return mdx string that represents the initial query
187: * @throws Throwable
188: * @deprecated
189: */
190: public static String getInitialQuery(String modelPath,
191: String connectionString, String cubeName) throws Throwable {
192: return getInitialQuery(modelPath, connectionString, cubeName,
193: null);
194: }
195:
196: /**
197: * @param modelPath
198: * @param jndi
199: * @param cubeName
200: * @param roleName
201: * @return mdx string that represents the initial query
202: * @throws Throwable
203: * @deprecated
204: */
205: public static String getInitialQuery(String modelPath, String jndi,
206: String cubeName, String roleName) throws Throwable {
207:
208: Properties properties = new Properties();
209:
210: if (modelPath.indexOf("http") == 0) { //$NON-NLS-1$
211: properties.put("Catalog", modelPath); //$NON-NLS-1$
212: } else {
213: if (!modelPath.startsWith("solution:")) { //$NON-NLS-1$
214: modelPath = "solution:" + modelPath; //$NON-NLS-1$
215: }
216: properties.put("Catalog", modelPath); //$NON-NLS-1$
217: }
218:
219: jndi = DatasourceHelper.getDSBoundName(jndi);
220:
221: properties.put("Provider", "mondrian"); //$NON-NLS-1$ //$NON-NLS-2$
222: properties.put("PoolNeeded", "false"); //$NON-NLS-1$ //$NON-NLS-2$
223: properties.put("dataSource", jndi); //$NON-NLS-1$
224:
225: if (roleName != null) {
226: properties.put("Role", roleName); //$NON-NLS-1$
227: }
228: return getInitialQuery(properties, cubeName);
229: }
230:
231: public static String getInitialQuery(Connection connection,
232: String cubeName) throws Throwable {
233:
234: String measuresMdx = null;
235: String columnsMdx = null;
236: StringBuffer rowsMdx = new StringBuffer();
237:
238: try {
239:
240: Schema schema = connection.getSchema();
241: if (schema == null) {
242: Logger
243: .error(
244: "MondrianModelComponent", Messages.getErrorString("MondrianModel.ERROR_0002_INVALID_SCHEMA", connection.getConnectString())); //$NON-NLS-1$ //$NON-NLS-2$
245: return null;
246: }
247:
248: Cube cubes[] = schema.getCubes();
249: if (cubes == null || cubes.length == 0) {
250: Logger
251: .error(
252: "MondrianModelComponent", Messages.getErrorString("MondrianModel.ERROR_0003_NO_CUBES", connection.getConnectString())); //$NON-NLS-1$ //$NON-NLS-2$
253: return null;
254: }
255:
256: if (cubes.length > 1 && cubeName == null) {
257: Logger
258: .error(
259: "MondrianModelComponent", Messages.getErrorString("MondrianModel.ERROR_0004_CUBE_NOT_SPECIFIED", connection.getConnectString())); //$NON-NLS-1$ //$NON-NLS-2$
260: return null;
261: }
262:
263: Cube cube = null;
264: if (cubes.length == 1) {
265: cube = cubes[0];
266: } else {
267: for (int n = 0; n < cubes.length; n++) {
268: if (cubes[n].getName().equals(cubeName)) {
269: cube = cubes[n];
270: break;
271: }
272: }
273: }
274:
275: if (cube == null) {
276: Logger
277: .error(
278: "MondrianModelComponent", Messages.getErrorString("MondrianModel.ERROR_0005_CUBE_NOT_FOUND", cubeName, connection.getConnectString())); //$NON-NLS-1$ //$NON-NLS-2$
279: return null;
280: }
281:
282: Dimension dimensions[] = cube.getDimensions();
283: if (dimensions == null || dimensions.length == 0) {
284: Logger
285: .error(
286: "MondrianModelComponent", Messages.getErrorString("MondrianModel.ERROR_0006_NO_DIMENSIONS", cubeName, connection.getConnectString())); //$NON-NLS-1$ //$NON-NLS-2$
287: return null;
288: }
289:
290: // now walk all the dimension.
291: for (int n = 0; n < dimensions.length; n++) {
292:
293: Hierarchy hierarchy = dimensions[n].getHierarchy();
294: if (hierarchy == null) {
295: Logger
296: .error(
297: "MondrianModelComponent", Messages.getErrorString("MondrianModel.ERROR_0007_NO_HIERARCHIES", dimensions[n].getName(), cubeName, connection.getConnectString())); //$NON-NLS-1$ //$NON-NLS-2$
298: return null;
299: }
300:
301: Member member = hierarchy.getDefaultMember();
302:
303: if (member == null) {
304: Logger
305: .error(
306: "MondrianModelComponent", Messages.getErrorString("MondrianModel.ERROR_0008_NO_DEFAULT_MEMBER", dimensions[n].getName(), cubeName, connection.getConnectString())); //$NON-NLS-1$ //$NON-NLS-2$
307: return null;
308: }
309: if (dimensions[n].isMeasures()) {
310: // measuresMdx = "with member "+ member.getUniqueName();
311: // //$NON-NLS-1$
312: measuresMdx = ""; //$NON-NLS-1$
313: columnsMdx = " select NON EMPTY {" + member.getUniqueName() + "} ON columns, "; //$NON-NLS-1$ //$NON-NLS-2$
314: } else {
315: if (rowsMdx.length() > 0) {
316: rowsMdx.append(", "); //$NON-NLS-1$
317: }
318: rowsMdx.append(member.getUniqueName());
319: }
320: }
321: if (measuresMdx != null && columnsMdx != null
322: && rowsMdx.length() > 0) {
323: StringBuffer result = new StringBuffer(measuresMdx
324: .length()
325: + columnsMdx.length() + rowsMdx.length() + 50);
326: result.append(measuresMdx).append(columnsMdx).append(
327: "NON EMPTY {(") //$NON-NLS-1$
328: .append(rowsMdx).append(")} ON rows ") //$NON-NLS-1$
329: .append("from [" + cube.getName() + "]"); //$NON-NLS-1$ //$NON-NLS-2$
330:
331: return result.toString();
332:
333: }
334: return null;
335: } catch (Throwable t) {
336: if (t instanceof MondrianException) {
337: // pull the cause out, otherwise it never gets logged
338: Throwable cause = ((MondrianException) t).getCause();
339: if (cause != null) {
340: throw cause;
341: } else {
342: throw t;
343: }
344: } else {
345: throw t;
346: }
347: }
348: }
349:
350: protected static SQLConnection getConnection(String jndiName,
351: String driver, String userId, String password,
352: String connectionInfo) {
353: SQLConnection connection = null;
354: try {
355: if (jndiName != null) {
356: connection = (SQLConnection) PentahoConnectionFactory
357: .getConnection(
358: IPentahoConnection.SQL_DATASOURCE,
359: jndiName, null);
360: }
361: if (connection == null) {
362: if (driver == null && connectionInfo == null) {
363: // TODO raise an error
364: }
365: connection = (SQLConnection) PentahoConnectionFactory
366: .getConnection(
367: IPentahoConnection.SQL_DATASOURCE,
368: driver, connectionInfo, userId,
369: password, null);
370: }
371: if (connection == null) {
372: Logger
373: .error(
374: "MondrianModelComponent", Messages.getErrorString("SQLBaseComponent.ERROR_0005_INVALID_CONNECTION")); //$NON-NLS-1$ //$NON-NLS-2$
375: return null;
376: }
377: return connection;
378: } catch (Exception e) {
379: Logger
380: .error(
381: "MondrianModelComponent", Messages.getErrorString("SQLBaseComponent.ERROR_0006_EXECUTE_FAILED", ""), e); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
382: }
383: return null;
384: }
385:
386: }
|