diff --git a/.classpath b/.classpath new file mode 100644 index 0000000..887e4cd --- /dev/null +++ b/.classpath @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/.project b/.project new file mode 100644 index 0000000..6851643 --- /dev/null +++ b/.project @@ -0,0 +1,28 @@ + + + com.jaspersoft.studio.data.mongodb + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/.settings/com.wdev91.eclipse.copyright.xml b/.settings/com.wdev91.eclipse.copyright.xml new file mode 100644 index 0000000..dd2b184 --- /dev/null +++ b/.settings/com.wdev91.eclipse.copyright.xml @@ -0,0 +1,17 @@ + + + + + diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..c537b63 --- /dev/null +++ b/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,7 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.6 diff --git a/META-INF/MANIFEST.MF b/META-INF/MANIFEST.MF new file mode 100644 index 0000000..b25cdd8 --- /dev/null +++ b/META-INF/MANIFEST.MF @@ -0,0 +1,14 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: MongoDB Plugin +Bundle-SymbolicName: com.jaspersoft.studio.data.mongodb;singleton:=true +Bundle-Version: 5.1.1.qualifier +Bundle-Activator: com.jaspersoft.studio.data.mongodb.Activator +Bundle-Vendor: Jaspersoft Corporation +Require-Bundle: com.jaspersoft.studio.data;bundle-version="5.1.1";visibility:=reexport, + com.jaspersoft.studio.server;bundle-version="5.1.1" +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Bundle-ActivationPolicy: lazy +Eclipse-RegisterBuddy: com.jaspersoft.studio.data +Bundle-ClassPath: lib/mongo-java-driver-2.7.3.jar, + . diff --git a/build.properties b/build.properties new file mode 100644 index 0000000..f13e545 --- /dev/null +++ b/build.properties @@ -0,0 +1,11 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + plugin.xml,\ + icons/,\ + lib/mongo-java-driver-2.7.3.jar,\ + src/,\ + resources/,\ + toc_dataadapters.xml,\ + html/ diff --git a/context.xml b/context.xml new file mode 100644 index 0000000..17ef068 --- /dev/null +++ b/context.xml @@ -0,0 +1,14 @@ + + + + + + MongoDB is an open source document-oriented database system developed and supported by 10gen. It is part of the NoSQL family of database systems. Instead of storing data in tables as is done in a "classical" relational database, MongoDB stores structured data as JSON-like documents with dynamic schemas (MongoDB calls the format BSON), making the integration of data in certain types of applications easier and faster. + + + + From this dialog you can change the dataset query, define new parameters or change the adapter used to retrive the data. + + + + diff --git a/html/mongodb.html b/html/mongodb.html new file mode 100644 index 0000000..00c026b --- /dev/null +++ b/html/mongodb.html @@ -0,0 +1,14 @@ + + + MongoDB is an open source document-oriented database system developed + and supported by 10gen. It is part of the NoSQL family of database + systems. Instead of storing data in tables as is done in a "classical" + relational database, MongoDB stores structured data as JSON-like + documents with dynamic schemas (MongoDB calls the format BSON), making + the integration of data in certain types of applications easier and + faster. +
+ website + + + \ No newline at end of file diff --git a/icons/datasource.png b/icons/datasource.png new file mode 100644 index 0000000..3a11197 Binary files /dev/null and b/icons/datasource.png differ diff --git a/icons/mongodb.png b/icons/mongodb.png new file mode 100644 index 0000000..0cd7d7d Binary files /dev/null and b/icons/mongodb.png differ diff --git a/lib/mongo-java-driver-2.7.3.jar b/lib/mongo-java-driver-2.7.3.jar new file mode 100644 index 0000000..24884da Binary files /dev/null and b/lib/mongo-java-driver-2.7.3.jar differ diff --git a/plugin.xml b/plugin.xml new file mode 100644 index 0000000..4163aac --- /dev/null +++ b/plugin.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..d8482fd --- /dev/null +++ b/pom.xml @@ -0,0 +1,16 @@ + + 4.0.0 + + + com.jaspersoft.studio.community-edition + plugins + 5.1.1-SNAPSHOT + ../aggregator/plugins/ + + + com.jaspersoft.studio.community-edition + com.jaspersoft.studio.data.mongodb + eclipse-plugin + 5.1.1-SNAPSHOT + \ No newline at end of file diff --git a/resources/icons.properties b/resources/icons.properties new file mode 100644 index 0000000..e18a920 --- /dev/null +++ b/resources/icons.properties @@ -0,0 +1,20 @@ +#------------------------------------------------------------------------------- +# Copyright (C) 2010 - 2013 Jaspersoft Corporation. All rights reserved. +# http://www.jaspersoft.com +# +# Unless you have purchased a commercial license agreement from Jaspersoft, +# the following license terms apply: +# +# This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Jaspersoft Studio Team - initial API and implementation +#------------------------------------------------------------------------------- +datasource-mongo.title=MongoDB Datasource +datasource-mongo.description=MongoDB Datasource +datasource-mongo.icon16=icons/mongodb.png +datasource-mongo.icon32=icons/mongodb.png + diff --git a/src/com/jaspersoft/mongodb/MongoDbDataSource.java b/src/com/jaspersoft/mongodb/MongoDbDataSource.java new file mode 100644 index 0000000..6a5c4f0 --- /dev/null +++ b/src/com/jaspersoft/mongodb/MongoDbDataSource.java @@ -0,0 +1,150 @@ +/******************************************************************************* + * Copyright (C) 2010 - 2013 Jaspersoft Corporation. All rights reserved. + * http://www.jaspersoft.com + * + * Unless you have purchased a commercial license agreement from Jaspersoft, + * the following license terms apply: + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Jaspersoft Studio Team - initial API and implementation + ******************************************************************************/ +package com.jaspersoft.mongodb; + +import java.util.Iterator; +import java.util.Map; + +import net.sf.jasperreports.engine.JRDataSource; +import net.sf.jasperreports.engine.JRException; +import net.sf.jasperreports.engine.JRField; + +import org.apache.log4j.Logger; + +import com.jaspersoft.mongodb.query.MongoDbQueryWrapper; +import com.mongodb.DBObject; + +/** + * An implementation of a data source that uses an empty query and parameters + * + * @author Eric Diaz + * + */ +public class MongoDbDataSource implements JRDataSource { + private MongoDbQueryWrapper wrapper; + + private DBObject currentDbObject; + + public static final String QUERY_LANGUAGE = "MongoDbQuery"; + + private static final Logger logger = Logger.getLogger(MongoDbDataSource.class); + + private boolean hasIterator = false; + + private boolean hasCommandResult = false; + + private Iterator resultsIterator; + + private Map currentResult; + + public MongoDbDataSource(MongoDbQueryWrapper wrapper) { + logger.info("New MongoDB Data Source"); + this.wrapper = wrapper; + hasIterator = wrapper.iterator != null; + if (!hasIterator) { + hasCommandResult = wrapper.commandResults != null; + resultsIterator = wrapper.commandResults.iterator(); + } + } + + /** + * Gets the field value for the current position. + */ + @Override + public Object getFieldValue(JRField field) throws JRException { + try { + if (field.getName() == null) { + return null; + } + String[] ids = field.getName().split("\\" + MongoDbFieldsProvider.FIELD_NAME_SEPARATOR); + if (hasIterator) { + return getCursorValue(ids); + } else if (hasCommandResult) { + return getCommandResult(ids); + } + return null; + } catch (Exception e) { + logger.error(e); + throw new JRException(e.getMessage()); + } + } + + private Object getCommandResult(String[] ids) { + Map currentMap = currentResult; + for (int index = 0; index < ids.length; index++) { + boolean isLast = index == (ids.length - 1); + String id = ids[index]; + Object currentFieldObject = currentMap.get(id); + if (currentFieldObject == null) { + return null; + } + if (currentFieldObject instanceof Map) { + if (isLast) { + return currentFieldObject; + } + currentMap = (Map) currentFieldObject; + } else { + if (isLast) { + return currentFieldObject; + } + return null; + } + } + return null; + } + + private Object getCursorValue(String[] ids) { + DBObject fieldObject = currentDbObject; + for (int index = 0; index < ids.length; index++) { + boolean isLast = index == (ids.length - 1); + String id = ids[index]; + Object currentFieldObject = fieldObject.get(id); + if (currentFieldObject == null) { + return null; + } + if (currentFieldObject instanceof DBObject) { + if (isLast) { + return currentFieldObject; + } + fieldObject = (DBObject) currentFieldObject; + } else { + if (isLast) { + return currentFieldObject; + } + return null; + } + } + return null; + } + + /** + * Tries to position the cursor on the next element in the data source. + */ + @Override + public boolean next() throws JRException { + boolean next = false; + if (hasIterator && (next = wrapper.iterator.hasNext())) { + currentDbObject = wrapper.iterator.next(); + } else if (hasCommandResult) { + next = resultsIterator.hasNext(); + currentResult = null; + if (next) { + currentResult = (Map) resultsIterator.next(); + } + } + return next; + } +} diff --git a/src/com/jaspersoft/mongodb/MongoDbFieldsProvider.java b/src/com/jaspersoft/mongodb/MongoDbFieldsProvider.java new file mode 100644 index 0000000..0cb89fe --- /dev/null +++ b/src/com/jaspersoft/mongodb/MongoDbFieldsProvider.java @@ -0,0 +1,182 @@ +/******************************************************************************* + * Copyright (C) 2010 - 2013 Jaspersoft Corporation. All rights reserved. + * http://www.jaspersoft.com + * + * Unless you have purchased a commercial license agreement from Jaspersoft, + * the following license terms apply: + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Jaspersoft Studio Team - initial API and implementation + ******************************************************************************/ +package com.jaspersoft.mongodb; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +import net.sf.jasperreports.engine.JRDataset; +import net.sf.jasperreports.engine.JRException; +import net.sf.jasperreports.engine.JRParameter; +import net.sf.jasperreports.engine.JRValueParameter; +import net.sf.jasperreports.engine.JasperReportsContext; +import net.sf.jasperreports.engine.design.JRDesignField; + +import org.apache.log4j.Logger; + +import com.jaspersoft.mongodb.connection.MongoDbConnection; +import com.jaspersoft.mongodb.query.MongoDbParameter; +import com.jaspersoft.mongodb.query.MongoDbQueryExecuter; +import com.jaspersoft.mongodb.query.MongoDbQueryWrapper; +import com.mongodb.BasicDBList; +import com.mongodb.BasicDBObject; +import com.mongodb.DBObject; + +/** + * + * @author Eric Diaz + * + */ +public class MongoDbFieldsProvider { + private static MongoDbFieldsProvider instance; + + private static final Lock lock = new ReentrantLock(); + + private static final Logger logger = Logger.getLogger(MongoDbFieldsProvider.class); + + public static final String FIELD_NAME_SEPARATOR = "."; + + private MongoDbFieldsProvider() { + + } + + public static MongoDbFieldsProvider getInstance() { + lock.lock(); + try { + if (instance == null) { + instance = new MongoDbFieldsProvider(); + } + return instance; + } finally { + lock.unlock(); + } + } + + public List getFields(JasperReportsContext context, JRDataset dataset, Map parameters, MongoDbConnection connection) + throws JRException { + MongoDbQueryExecuter queryExecuter = null; + MongoDbQueryWrapper wrapper = null; + try { + Map newValueParameters = new HashMap(); + for (String parameterName : parameters.keySet()) { + Object parameterValue = parameters.get(parameterName); + MongoDbParameter newParameter = new MongoDbParameter(parameterName, parameterValue); + newValueParameters.put(parameterName, newParameter); + } + parameters.clear(); + newValueParameters.put(JRParameter.REPORT_PARAMETERS_MAP, new MongoDbParameter( + JRParameter.REPORT_PARAMETERS_MAP, parameters)); + queryExecuter = new MongoDbQueryExecuter(context, dataset, newValueParameters, true); + wrapper = new MongoDbQueryWrapper(queryExecuter.getProcessedQueryString(), connection, + queryExecuter.getParameters()); + logger.info("FieldsProvider will find fields from the first " + wrapper.rowsToProcess + " records."); + Map> fieldNames = new TreeMap>(); + if (wrapper.iterator != null) { + processCursorFields(wrapper, fieldNames); + } else if (wrapper.commandResults != null) { + processCommandResultFields(wrapper, fieldNames); + } + List fields = new ArrayList(); + JRDesignField field = null; + logger.info("Found " + fieldNames.keySet().size() + " fields"); + for (String fieldName : fieldNames.keySet()) { + field = new JRDesignField(); + field.setName(fieldName); + field.setValueClass(fieldNames.get(fieldName)); + field.setDescription(null); + fields.add(field); + } + return fields; + } finally { + if (connection != null) { + connection.close(); + } + } + } + + private void processCommandResultFields(MongoDbQueryWrapper wrapper, Map> fieldNames) { + Iterator resultsIterator = wrapper.commandResults.iterator(); + while (resultsIterator.hasNext() && wrapper.rowsToProcess >= 0) { + Map currentResult = (Map) resultsIterator.next(); + processMapResult(null, currentResult, fieldNames); + wrapper.rowsToProcess--; + } + } + + private void processCursorFields(MongoDbQueryWrapper wrapper, Map> fieldNames) { + try { + DBObject currentDbObject; + while (wrapper.iterator.hasNext() && wrapper.rowsToProcess >= 0) { + currentDbObject = wrapper.iterator.next(); + processDBObject(null, currentDbObject, fieldNames); + wrapper.rowsToProcess--; + } + } finally { + if (wrapper.iterator != null) { + wrapper.iterator.close(); + } + } + } + + private void processMapResult(String parentFieldName, Map currentResult, Map> fieldNames) { + Object value; + if (logger.isDebugEnabled()) { + logger.debug("processDBObject parentFieldName: " + parentFieldName); + logger.debug("processDBObject currentDbObject: " + currentResult.toString()); + } + for (Object fieldName : currentResult.keySet()) { + value = currentResult.get(fieldName); + if (value == null) { + continue; + } + if (value instanceof Map) { + processMapResult((parentFieldName == null ? "" : parentFieldName + FIELD_NAME_SEPARATOR) + fieldName, + (Map) value, fieldNames); + } else { + fieldNames.put((parentFieldName == null ? "" : parentFieldName + FIELD_NAME_SEPARATOR) + fieldName, + value.getClass()); + } + } + } + + private void processDBObject(String parentFieldName, DBObject currentDbObject, Map> fieldNames) { + Object value; + if (logger.isDebugEnabled()) { + logger.debug("processDBObject parentFieldName: " + parentFieldName); + logger.debug("processDBObject currentDbObject: " + currentDbObject.toString()); + } + for (String fieldName : currentDbObject.keySet()) { + value = currentDbObject.get(fieldName); + if (value == null) { + continue; + } + if (value instanceof BasicDBList) { + fieldNames.put((parentFieldName == null ? "" : parentFieldName + ".") + fieldName, List.class); + } else if (value instanceof BasicDBObject) { + processDBObject((parentFieldName == null ? "" : parentFieldName + ".") + fieldName, (DBObject) value, + fieldNames); + } else { + fieldNames.put((parentFieldName == null ? "" : parentFieldName + ".") + fieldName, value.getClass()); + } + } + } +} diff --git a/src/com/jaspersoft/mongodb/adapter/MongoDbDataAdapter.java b/src/com/jaspersoft/mongodb/adapter/MongoDbDataAdapter.java new file mode 100644 index 0000000..39e556f --- /dev/null +++ b/src/com/jaspersoft/mongodb/adapter/MongoDbDataAdapter.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (C) 2010 - 2013 Jaspersoft Corporation. All rights reserved. + * http://www.jaspersoft.com + * + * Unless you have purchased a commercial license agreement from Jaspersoft, + * the following license terms apply: + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Jaspersoft Studio Team - initial API and implementation + ******************************************************************************/ +package com.jaspersoft.mongodb.adapter; + +import net.sf.jasperreports.data.DataAdapter; + +/** + * @author Eric Diaz + */ +public interface MongoDbDataAdapter extends DataAdapter { + public void setMongoURI(String mongoURI); + + public String getMongoURI(); + + public void setUsername(String username); + + public String getUsername(); + + public void setPassword(String password); + + public String getPassword(); +} diff --git a/src/com/jaspersoft/mongodb/adapter/MongoDbDataAdapterImplementation.java b/src/com/jaspersoft/mongodb/adapter/MongoDbDataAdapterImplementation.java new file mode 100644 index 0000000..4073ac4 --- /dev/null +++ b/src/com/jaspersoft/mongodb/adapter/MongoDbDataAdapterImplementation.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright (C) 2010 - 2013 Jaspersoft Corporation. All rights reserved. + * http://www.jaspersoft.com + * + * Unless you have purchased a commercial license agreement from Jaspersoft, + * the following license terms apply: + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Jaspersoft Studio Team - initial API and implementation + ******************************************************************************/ +package com.jaspersoft.mongodb.adapter; + +import net.sf.jasperreports.data.AbstractDataAdapter; + +/** + * @author Eric Diaz + */ +public class MongoDbDataAdapterImplementation extends AbstractDataAdapter implements MongoDbDataAdapter { + private String mongoURI; + + private String username; + + private String password; + + public void setMongoURI(String mongoURI) { + this.mongoURI = mongoURI; + } + + public String getMongoURI() { + return mongoURI; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getUsername() { + return username; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getPassword() { + return password; + } +} diff --git a/src/com/jaspersoft/mongodb/adapter/MongoDbDataAdapterImplementation.xml b/src/com/jaspersoft/mongodb/adapter/MongoDbDataAdapterImplementation.xml new file mode 100755 index 0000000..fb5ada4 --- /dev/null +++ b/src/com/jaspersoft/mongodb/adapter/MongoDbDataAdapterImplementation.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/com/jaspersoft/mongodb/adapter/MongoDbDataAdapterService.java b/src/com/jaspersoft/mongodb/adapter/MongoDbDataAdapterService.java new file mode 100644 index 0000000..469e1bd --- /dev/null +++ b/src/com/jaspersoft/mongodb/adapter/MongoDbDataAdapterService.java @@ -0,0 +1,89 @@ +/******************************************************************************* + * Copyright (C) 2010 - 2013 Jaspersoft Corporation. All rights reserved. + * http://www.jaspersoft.com + * + * Unless you have purchased a commercial license agreement from Jaspersoft, + * the following license terms apply: + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Jaspersoft Studio Team - initial API and implementation + ******************************************************************************/ +package com.jaspersoft.mongodb.adapter; + +import java.util.Map; + +import net.sf.jasperreports.data.AbstractDataAdapterService; +import net.sf.jasperreports.engine.JRException; +import net.sf.jasperreports.engine.JRParameter; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.jaspersoft.mongodb.connection.MongoDbConnection; + +/** + * @author Teodor Danciu (teodord@users.sourceforge.net) + * @version $Id$ + * @author Eric Diaz + */ +public class MongoDbDataAdapterService extends AbstractDataAdapterService { + private static final Log log = LogFactory.getLog(MongoDbDataAdapterService.class); + + private MongoDbConnection connection; + + private MongoDbDataAdapter dataAdapter; + + public MongoDbDataAdapterService(MongoDbDataAdapter dataAdapter) { + this.dataAdapter = dataAdapter; + } + + @Override + public void contributeParameters(Map parameters) throws JRException { + if (connection != null) { + dispose(); + } + if (dataAdapter != null) { + try { + createConnection(); + parameters.put(JRParameter.REPORT_CONNECTION, connection); + } catch (Exception e) { + throw new JRException(e); + } + } + } + + private void createConnection() throws JRException { + connection = new MongoDbConnection(dataAdapter.getMongoURI(), dataAdapter.getUsername(), + dataAdapter.getPassword()); + } + + @Override + public void dispose() { + try { + if (connection != null) + connection.close(); + } catch (Exception e) { + e.printStackTrace(); + if (log.isErrorEnabled()) + log.error("Error while closing the connection.", e); + } + } + + @Override + public void test() throws JRException { + try { + if (connection != null) { + } else { + createConnection(); + } + connection.test(); + } finally { + dispose(); + } + } +} diff --git a/src/com/jaspersoft/mongodb/connection/MongoDbConnection.java b/src/com/jaspersoft/mongodb/connection/MongoDbConnection.java new file mode 100644 index 0000000..c48a82d --- /dev/null +++ b/src/com/jaspersoft/mongodb/connection/MongoDbConnection.java @@ -0,0 +1,450 @@ +/******************************************************************************* + * Copyright (C) 2010 - 2013 Jaspersoft Corporation. All rights reserved. + * http://www.jaspersoft.com + * + * Unless you have purchased a commercial license agreement from Jaspersoft, + * the following license terms apply: + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Jaspersoft Studio Team - initial API and implementation + ******************************************************************************/ +package com.jaspersoft.mongodb.connection; + +import java.sql.Array; +import java.sql.Blob; +import java.sql.CallableStatement; +import java.sql.Clob; +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.NClob; +import java.sql.PreparedStatement; +import java.sql.SQLClientInfoException; +import java.sql.SQLException; +import java.sql.SQLWarning; +import java.sql.SQLXML; +import java.sql.Savepoint; +import java.sql.Statement; +import java.sql.Struct; +import java.util.Map; +import java.util.Properties; +import java.util.concurrent.Executor; + +import net.sf.jasperreports.engine.JRException; + +import org.apache.log4j.Logger; + +import com.mongodb.DB; +import com.mongodb.Mongo; +import com.mongodb.MongoException; +import com.mongodb.MongoURI; + +/** + * + * @author Eric Diaz + * + */ +public class MongoDbConnection implements Connection { + private Mongo client; + + private MongoURI mongoURIObject; + + private String mongoURI; + + private String username; + + private String password; + + private DB mongoDatabase; + + private final Logger logger = Logger.getLogger(MongoDbConnection.class); + + public MongoDbConnection(String mongoURI, String username, String password) + throws JRException { + create(this.mongoURI = mongoURI); + this.username = username; + this.password = password; + setDatabase(); + } + + private void create(String mongoURI) throws JRException { + close(); + try { + client = new Mongo(mongoURIObject = new MongoURI(mongoURI)); + } catch (Exception e) { + logger.error(e); + throw new JRException(e.getMessage()); + } + } + + private void setDatabase() throws JRException { + if (client == null) { + logger.error("No client"); + return; + } + if (mongoDatabase != null) { + return; + } + mongoDatabase = client.getDB(mongoURIObject.getDatabase()); + boolean performaAuthentication = false; + try { + mongoDatabase.getCollectionNames(); + } catch (Exception e) { + String message = e.getMessage(); + if (e instanceof MongoException) { + if (message != null && message.startsWith("unauthorized db")) { + performaAuthentication = true; + } else { + logger.error(e); + throw new JRException(message); + } + } else { + logger.error(e); + throw new JRException(message); + } + } + if (performaAuthentication) { + if (username != null && password != null) { + if (!mongoDatabase.authenticate(username, + password.toCharArray())) { + throw new JRException( + "Successful connection but wrong authentication"); + } + } else { + throw new JRException( + "Authentication required but username or password is empty"); + } + } + } + + public DB getMongoDatabase() { + return mongoDatabase; + } + + public String getMongoURI() { + return mongoURI; + } + + public String getUsername() { + return username; + } + + public String getPassword() { + return password; + } + + @Override + public void close() { + if (client != null) { + client.close(); + client = null; + } + mongoURIObject = null; + } + + @Override + public boolean isClosed() throws SQLException { + if (client != null) { + return false; + } + return true; + } + + public MongoURI getMongoURIObject() { + return mongoURIObject; + } + + public Mongo getClient() { + return client; + } + + public String test() throws JRException { + if (mongoURIObject == null) { + throw new JRException("Invalid mongo URL"); + } + + if (mongoDatabase == null) { + throw new JRException("No mongo database"); + } + + try { + return "Connection test successful.\n" + "Mongo database name: " + + mongoDatabase.getName(); + } catch (Exception e) { + logger.error(e); + throw new JRException(e); + } + } + + public void getDatabase(String databaseName) { + + } + + @Override + public T unwrap(Class iface) throws SQLException { + return null; + } + + @Override + public boolean isWrapperFor(Class iface) throws SQLException { + return false; + } + + @Override + public Statement createStatement() throws SQLException { + return null; + } + + @Override + public PreparedStatement prepareStatement(String sql) throws SQLException { + return null; + } + + @Override + public CallableStatement prepareCall(String sql) throws SQLException { + return null; + } + + @Override + public String nativeSQL(String sql) throws SQLException { + return null; + } + + @Override + public void setAutoCommit(boolean autoCommit) throws SQLException { + } + + @Override + public boolean getAutoCommit() throws SQLException { + return false; + } + + @Override + public void commit() throws SQLException { + } + + @Override + public void rollback() throws SQLException { + } + + @Override + public DatabaseMetaData getMetaData() throws SQLException { + return null; + } + + @Override + public void setReadOnly(boolean readOnly) throws SQLException { + } + + @Override + public boolean isReadOnly() throws SQLException { + return false; + } + + @Override + public void setCatalog(String catalog) throws SQLException { + } + + @Override + public String getCatalog() throws SQLException { + return null; + } + + @Override + public void setTransactionIsolation(int level) throws SQLException { + } + + @Override + public int getTransactionIsolation() throws SQLException { + return 0; + } + + @Override + public SQLWarning getWarnings() throws SQLException { + return null; + } + + @Override + public void clearWarnings() throws SQLException { + } + + @Override + public Statement createStatement(int resultSetType, int resultSetConcurrency) + throws SQLException { + return null; + } + + @Override + public PreparedStatement prepareStatement(String sql, int resultSetType, + int resultSetConcurrency) throws SQLException { + return null; + } + + @Override + public CallableStatement prepareCall(String sql, int resultSetType, + int resultSetConcurrency) throws SQLException { + return null; + } + + @Override + public Map> getTypeMap() throws SQLException { + return null; + } + + @Override + public void setTypeMap(Map> map) throws SQLException { + } + + @Override + public void setHoldability(int holdability) throws SQLException { + } + + @Override + public int getHoldability() throws SQLException { + return 0; + } + + @Override + public Savepoint setSavepoint() throws SQLException { + return null; + } + + @Override + public Savepoint setSavepoint(String name) throws SQLException { + return null; + } + + @Override + public void rollback(Savepoint savepoint) throws SQLException { + } + + @Override + public void releaseSavepoint(Savepoint savepoint) throws SQLException { + } + + @Override + public Statement createStatement(int resultSetType, + int resultSetConcurrency, int resultSetHoldability) + throws SQLException { + return null; + } + + @Override + public PreparedStatement prepareStatement(String sql, int resultSetType, + int resultSetConcurrency, int resultSetHoldability) + throws SQLException { + return null; + } + + @Override + public CallableStatement prepareCall(String sql, int resultSetType, + int resultSetConcurrency, int resultSetHoldability) + throws SQLException { + return null; + } + + @Override + public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) + throws SQLException { + return null; + } + + @Override + public PreparedStatement prepareStatement(String sql, int[] columnIndexes) + throws SQLException { + return null; + } + + @Override + public PreparedStatement prepareStatement(String sql, String[] columnNames) + throws SQLException { + return null; + } + + @Override + public Clob createClob() throws SQLException { + return null; + } + + @Override + public Blob createBlob() throws SQLException { + return null; + } + + @Override + public NClob createNClob() throws SQLException { + return null; + } + + @Override + public SQLXML createSQLXML() throws SQLException { + return null; + } + + @Override + public boolean isValid(int timeout) throws SQLException { + return false; + } + + @Override + public void setClientInfo(String name, String value) + throws SQLClientInfoException { + } + + @Override + public void setClientInfo(Properties properties) + throws SQLClientInfoException { + } + + @Override + public String getClientInfo(String name) throws SQLException { + return null; + } + + @Override + public Properties getClientInfo() throws SQLException { + return null; + } + + @Override + public Array createArrayOf(String typeName, Object[] elements) + throws SQLException { + return null; + } + + @Override + public Struct createStruct(String typeName, Object[] attributes) + throws SQLException { + return null; + } + + public void setSchema(String schema) throws SQLException { + // TODO Auto-generated method stub + + } + + public String getSchema() throws SQLException { + // TODO Auto-generated method stub + return null; + } + + public void abort(Executor executor) throws SQLException { + // TODO Auto-generated method stub + + } + + public void setNetworkTimeout(Executor executor, int milliseconds) + throws SQLException { + // TODO Auto-generated method stub + + } + + public int getNetworkTimeout() throws SQLException { + // TODO Auto-generated method stub + return 0; + } +} diff --git a/src/com/jaspersoft/mongodb/connection/MongoDbConnectionFactory.java b/src/com/jaspersoft/mongodb/connection/MongoDbConnectionFactory.java new file mode 100644 index 0000000..86505b9 --- /dev/null +++ b/src/com/jaspersoft/mongodb/connection/MongoDbConnectionFactory.java @@ -0,0 +1,88 @@ +/******************************************************************************* + * Copyright (C) 2010 - 2013 Jaspersoft Corporation. All rights reserved. + * http://www.jaspersoft.com + * + * Unless you have purchased a commercial license agreement from Jaspersoft, + * the following license terms apply: + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Jaspersoft Studio Team - initial API and implementation + ******************************************************************************/ +package com.jaspersoft.mongodb.connection; + +import net.sf.jasperreports.engine.JRException; + +import org.apache.commons.pool.PoolableObjectFactory; +import org.apache.log4j.Logger; + +/** + * + * @author Eric Diaz + * + */ +public class MongoDbConnectionFactory implements PoolableObjectFactory { + private final Logger logger = Logger.getLogger(MongoDbConnectionFactory.class); + + private String mongoURI; + + private String username; + + private String password; + + @Override + public void activateObject(MongoDbConnection connection) throws Exception { + } + + @Override + public void destroyObject(MongoDbConnection connection) throws Exception { + logger.info("Factory destroy object"); + if (connection != null) { + connection.close(); + } + } + + @Override + public MongoDbConnection makeObject() throws Exception { + logger.info("Factory make object"); + return new MongoDbConnection(mongoURI, username, password); + } + + @Override + public void passivateObject(MongoDbConnection connection) throws Exception { + if (logger.isDebugEnabled()) { + logger.debug("Passivate is not implemented"); + } + } + + @Override + public boolean validateObject(MongoDbConnection connection) { + logger.info("Factory validate object"); + if (connection != null) { + try { + return (mongoURI != null && mongoURI.equals(connection.getMongoURI())) + && (username == null ? true : username.equals(connection.getUsername())) + && (password == null ? true : password.equals(connection.getPassword())) && (connection.test() != null); + } catch (JRException e) { + logger.error(e); + } + } + return false; + } + + public void setMongoURI(String mongoURI) { + this.mongoURI = mongoURI; + } + + public void setUsername(String username) { + this.username = username; + } + + public void setPassword(String password) { + this.password = password; + } +} diff --git a/src/com/jaspersoft/mongodb/connection/MongoDbConnectionManager.java b/src/com/jaspersoft/mongodb/connection/MongoDbConnectionManager.java new file mode 100644 index 0000000..4a05ec3 --- /dev/null +++ b/src/com/jaspersoft/mongodb/connection/MongoDbConnectionManager.java @@ -0,0 +1,117 @@ +/******************************************************************************* + * Copyright (C) 2010 - 2013 Jaspersoft Corporation. All rights reserved. + * http://www.jaspersoft.com + * + * Unless you have purchased a commercial license agreement from Jaspersoft, + * the following license terms apply: + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Jaspersoft Studio Team - initial API and implementation + ******************************************************************************/ +package com.jaspersoft.mongodb.connection; + +import org.apache.commons.pool.impl.GenericObjectPool; +import org.apache.commons.pool.impl.GenericObjectPool.Config; +import org.apache.log4j.Logger; + +/** + * + * @author Eric Diaz + * + */ +public class MongoDbConnectionManager { + private GenericObjectPool connectionsPool; + + private Config poolConfiguration; + + private MongoDbConnectionFactory connectionFactory; + + private final Logger logger = Logger.getLogger(MongoDbConnectionManager.class); + + public MongoDbConnectionManager() { + connectionFactory = new MongoDbConnectionFactory(); + poolConfiguration = new Config(); + poolConfiguration.testOnBorrow = true; + poolConfiguration.testWhileIdle = true; + poolConfiguration.whenExhaustedAction = GenericObjectPool.WHEN_EXHAUSTED_GROW; + poolConfiguration.maxActive = 4; + poolConfiguration.maxIdle = 2; + poolConfiguration.minIdle = 1; + } + + private GenericObjectPool startConnectionsPool() { + if (connectionsPool == null) { + connectionsPool = new GenericObjectPool(connectionFactory, poolConfiguration); + } + return connectionsPool; + } + + public MongoDbConnection borrowConnection() throws Exception { + if (connectionsPool == null) { + startConnectionsPool(); + } + if (connectionsPool == null) { + logger.error("No connection pool created"); + return null; + } + if (logger.isDebugEnabled()) { + logger.debug("Current active connections before borrow: " + connectionsPool.getNumActive()); + } + return connectionsPool.borrowObject(); + } + + public void returnConnection(MongoDbConnection connection) { + if (connectionsPool == null) { + logger.error("No connection pool created"); + return; + } + try { + connectionsPool.returnObject(connection); + if (logger.isDebugEnabled()) { + logger.debug("Current active connections on return: " + connectionsPool.getNumActive()); + } + } catch (Exception e) { + logger.error(e); + } + } + + public void shutdown() { + if (connectionsPool != null) { + try { + connectionsPool.clear(); + connectionsPool.close(); + } catch (Exception e) { + logger.error(e); + } + } + } + + public void setMaxActive(int maxActive) { + poolConfiguration.maxActive = maxActive; + } + + public void setMaxIdle(int maxIdle) { + poolConfiguration.maxIdle = maxIdle; + } + + public void setMinIdle(int minIdle) { + poolConfiguration.minIdle = minIdle; + } + + public void setMongoURI(String mongoURI) { + connectionFactory.setMongoURI(mongoURI); + } + + public void setUsername(String username) { + connectionFactory.setUsername(username); + } + + public void setPassword(String password) { + connectionFactory.setPassword(password); + } +} diff --git a/src/com/jaspersoft/mongodb/query/MongoDbParameter.java b/src/com/jaspersoft/mongodb/query/MongoDbParameter.java new file mode 100644 index 0000000..bf7cf38 --- /dev/null +++ b/src/com/jaspersoft/mongodb/query/MongoDbParameter.java @@ -0,0 +1,121 @@ +/******************************************************************************* + * Copyright (C) 2010 - 2013 Jaspersoft Corporation. All rights reserved. + * http://www.jaspersoft.com + * + * Unless you have purchased a commercial license agreement from Jaspersoft, + * the following license terms apply: + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Jaspersoft Studio Team - initial API and implementation + ******************************************************************************/ +package com.jaspersoft.mongodb.query; + +import net.sf.jasperreports.engine.JRExpression; +import net.sf.jasperreports.engine.JRPropertiesHolder; +import net.sf.jasperreports.engine.JRPropertiesMap; +import net.sf.jasperreports.engine.JRValueParameter; + +/** + * + * @author Eric Diaz + * + */ +public class MongoDbParameter implements JRValueParameter { + + private String name; + + private Object value; + + public MongoDbParameter(String name, Object value) { + this.name = name; + this.value = value; + } + + public Object clone() { + return null; + } + + @Override + public boolean hasProperties() { + return false; + } + + @Override + public String getName() { + return name; + } + + @Override + public String getDescription() { + return null; + } + + @Override + public void setDescription(String description) { + } + + @Override + public Class getValueClass() { + if (value != null) { + return value.getClass(); + } + return null; + } + + @Override + public String getValueClassName() { + if (value != null) { + return value.getClass().getName(); + } + return null; + } + + @Override + public boolean isSystemDefined() { + return false; + } + + @Override + public boolean isForPrompting() { + return false; + } + + @Override + public JRExpression getDefaultValueExpression() { + return null; + } + + @Override + public Class getNestedType() { + return null; + } + + @Override + public String getNestedTypeName() { + return null; + } + + @Override + public JRPropertiesMap getPropertiesMap() { + return null; + } + + @Override + public JRPropertiesHolder getParentProperties() { + return null; + } + + @Override + public Object getValue() { + return value; + } + + @Override + public void setValue(Object value) { + } +} diff --git a/src/com/jaspersoft/mongodb/query/MongoDbQueryExecuter.java b/src/com/jaspersoft/mongodb/query/MongoDbQueryExecuter.java new file mode 100644 index 0000000..cd097b1 --- /dev/null +++ b/src/com/jaspersoft/mongodb/query/MongoDbQueryExecuter.java @@ -0,0 +1,189 @@ +/******************************************************************************* + * Copyright (C) 2010 - 2013 Jaspersoft Corporation. All rights reserved. + * http://www.jaspersoft.com + * + * Unless you have purchased a commercial license agreement from Jaspersoft, + * the following license terms apply: + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Jaspersoft Studio Team - initial API and implementation + ******************************************************************************/ +package com.jaspersoft.mongodb.query; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import net.sf.jasperreports.engine.JRDataSource; +import net.sf.jasperreports.engine.JRDataset; +import net.sf.jasperreports.engine.JRException; +import net.sf.jasperreports.engine.JRParameter; +import net.sf.jasperreports.engine.JRRuntimeException; +import net.sf.jasperreports.engine.JRValueParameter; +import net.sf.jasperreports.engine.JasperReportsContext; +import net.sf.jasperreports.engine.query.JRAbstractQueryExecuter; + +import org.apache.log4j.Logger; + +import com.jaspersoft.mongodb.MongoDbDataSource; +import com.jaspersoft.mongodb.connection.MongoDbConnection; + +/** + * A query executer for pseudo mongodb queries
+ * This implementation process report parameters + * + * @author Eric Diaz + * + */ +public class MongoDbQueryExecuter extends JRAbstractQueryExecuter { + private final static Logger logger = Logger + .getLogger(MongoDbQueryExecuter.class); + + private Map reportParameters; + + private Map parameters; + + private MongoDbQueryWrapper wrapper; + + private boolean directParameters; + + public MongoDbQueryExecuter(JasperReportsContext jasperReportsContext, + JRDataset dataset, + Map parameters) + throws JRException { + this(jasperReportsContext, dataset, parameters, false); + } + + public MongoDbQueryExecuter(JasperReportsContext jasperReportsContext, + JRDataset dataset, + Map parameters, + boolean directParameters) { + super(jasperReportsContext, dataset, parameters); + this.directParameters = directParameters; + this.reportParameters = parameters; + this.parameters = new HashMap(); + parseQuery(); + } + + /** + * Method not implemented + */ + @Override + public boolean cancelQuery() throws JRException { + logger.warn("Cancel not implemented"); + return false; + } + + @Override + public void close() { + wrapper = null; + } + + private MongoDbConnection processConnection(JRValueParameter valueParameter) + throws JRException { + if (valueParameter == null) { + throw new JRException("No MongoDB connection"); + } + return (MongoDbConnection) valueParameter.getValue(); + } + + /** + * Creates a new {@link MongoDbDataSource} from the report parameters and + * the query string + */ + public JRDataSource createDatasource() throws JRException { + MongoDbConnection connection = (MongoDbConnection) ((Map) getParameterValue(JRParameter.REPORT_PARAMETERS_MAP)) + .get(JRParameter.REPORT_CONNECTION); + if (connection == null) { + if (logger.isDebugEnabled()) { + logger.debug("REPORT_PARAMETERS_MAP: " + + ((Map) getParameterValue(JRParameter.REPORT_PARAMETERS_MAP)) + .keySet()); + } + if (logger.isDebugEnabled()) { + logger.debug("Direct parameters: " + reportParameters.keySet()); + } + connection = processConnection(reportParameters + .get(JRParameter.REPORT_CONNECTION)); + if (connection == null) { + throw new JRException("No MongoDB connection"); + } + } + wrapper = new MongoDbQueryWrapper(getQueryString(), connection, + parameters); + return new MongoDbDataSource(wrapper); + } + + /** + * Replacement of parameters + */ + @Override + protected String getParameterReplacement(String parameterName) { + Object parameterValue = reportParameters.get(parameterName); + if (parameterValue == null) { + throw new JRRuntimeException("Parameter \"" + parameterName + + "\" does not exist."); + } + if (parameterValue instanceof JRValueParameter) { + parameterValue = ((JRValueParameter) parameterValue).getValue(); + } + return processParameter(parameterName, parameterValue); + } + + private String processParameter(String parameterName, Object parameterValue) { + if (parameterValue instanceof Collection) { + StringBuilder builder = new StringBuilder(); + builder.append("["); + for (Object value : (Collection) parameterValue) { + if (value instanceof String) { + builder.append("'"); + builder.append(value); + builder.append("'"); + } else { + builder.append(String.valueOf(value)); + } + builder.append(", "); + } + if (builder.length() > 2) { + builder.delete(builder.length() - 2, builder.length()); + } + builder.append("]"); + return builder.toString(); + } + parameters.put(parameterName, parameterValue); + return generateParameterObject(parameterName); + } + + private String generateParameterObject(String parameterName) { + return "{'" + parameterName + "':null}"; + } + + public String getProcessedQueryString() { + return getQueryString(); + } + + @Override + protected Object getParameterValue(String parameterName, + boolean ignoreMissing) { + try { + return super.getParameterValue(parameterName, ignoreMissing); + } catch (Exception e) { + if (e.getMessage() + .endsWith( + "cannot be cast to net.sf.jasperreports.engine.JRValueParameter") + && directParameters) { + return reportParameters.get(parameterName); + } + } + return null; + } + + public Map getParameters() { + return parameters; + } +} diff --git a/src/com/jaspersoft/mongodb/query/MongoDbQueryExecuterExtensionsRegistryFactory.java b/src/com/jaspersoft/mongodb/query/MongoDbQueryExecuterExtensionsRegistryFactory.java new file mode 100644 index 0000000..e829708 --- /dev/null +++ b/src/com/jaspersoft/mongodb/query/MongoDbQueryExecuterExtensionsRegistryFactory.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (C) 2010 - 2013 Jaspersoft Corporation. All rights reserved. + * http://www.jaspersoft.com + * + * Unless you have purchased a commercial license agreement from Jaspersoft, + * the following license terms apply: + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Jaspersoft Studio Team - initial API and implementation + ******************************************************************************/ +package com.jaspersoft.mongodb.query; + +import java.util.Collections; +import java.util.List; + +import net.sf.jasperreports.engine.JRPropertiesMap; +import net.sf.jasperreports.engine.query.JRQueryExecuterFactoryBundle; +import net.sf.jasperreports.extensions.ExtensionsRegistry; +import net.sf.jasperreports.extensions.ExtensionsRegistryFactory; + +/** + * + * @author Eric Diaz + * + */ +public class MongoDbQueryExecuterExtensionsRegistryFactory implements + ExtensionsRegistryFactory { + private static final ExtensionsRegistry defaultExtensionsRegistry = new ExtensionsRegistry() { + @SuppressWarnings("unchecked") + public List getExtensions(Class extensionType) { + if (JRQueryExecuterFactoryBundle.class.equals(extensionType)) { + return (List) Collections + .singletonList(MongoDbQueryExecuterFactoryBundle + .getInstance()); + } + return null; + } + }; + + public ExtensionsRegistry createRegistry(String registryId, + JRPropertiesMap properties) { + return defaultExtensionsRegistry; + } +} diff --git a/src/com/jaspersoft/mongodb/query/MongoDbQueryExecuterFactory.java b/src/com/jaspersoft/mongodb/query/MongoDbQueryExecuterFactory.java new file mode 100644 index 0000000..7c3660d --- /dev/null +++ b/src/com/jaspersoft/mongodb/query/MongoDbQueryExecuterFactory.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (C) 2010 - 2013 Jaspersoft Corporation. All rights reserved. + * http://www.jaspersoft.com + * + * Unless you have purchased a commercial license agreement from Jaspersoft, + * the following license terms apply: + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Jaspersoft Studio Team - initial API and implementation + ******************************************************************************/ +package com.jaspersoft.mongodb.query; + +import java.util.Map; + +import net.sf.jasperreports.engine.DefaultJasperReportsContext; +import net.sf.jasperreports.engine.JRDataset; +import net.sf.jasperreports.engine.JRException; +import net.sf.jasperreports.engine.JRValueParameter; +import net.sf.jasperreports.engine.JasperReportsContext; +import net.sf.jasperreports.engine.query.JRQueryExecuter; +import net.sf.jasperreports.engine.query.QueryExecuterFactory; + +/** + * Query executer factory for MongoDB pseudo queries.
+ * This factory creates a {@link MongoDbQueryExecuter} + * + * @author Eric Diaz + * + */ +public class MongoDbQueryExecuterFactory implements QueryExecuterFactory { + /** + * Creates a {@link MongoDbQueryExecuter}.
+ *
+ * This method is called at fill time for reports/datasets having a query + * supported by this factory (MongoDbQuery). + */ + public JRQueryExecuter createQueryExecuter(JRDataset dataset, + Map parameters) + throws JRException { + return new MongoDbQueryExecuter( + DefaultJasperReportsContext.getInstance(), dataset, parameters); + }; + + /** + * Method not implemented + */ + public Object[] getBuiltinParameters() { + return null; + } + + public boolean supportsQueryParameterType(String queryParameterType) { + return true; + } + + @Override + public JRQueryExecuter createQueryExecuter( + JasperReportsContext jasperReportsContext, JRDataset dataset, + Map parameters) + throws JRException { + return new MongoDbQueryExecuter(jasperReportsContext, dataset, + parameters); + } + +} diff --git a/src/com/jaspersoft/mongodb/query/MongoDbQueryExecuterFactoryBundle.java b/src/com/jaspersoft/mongodb/query/MongoDbQueryExecuterFactoryBundle.java new file mode 100644 index 0000000..7e9a0fa --- /dev/null +++ b/src/com/jaspersoft/mongodb/query/MongoDbQueryExecuterFactoryBundle.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright (C) 2010 - 2013 Jaspersoft Corporation. All rights reserved. + * http://www.jaspersoft.com + * + * Unless you have purchased a commercial license agreement from Jaspersoft, + * the following license terms apply: + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Jaspersoft Studio Team - initial API and implementation + ******************************************************************************/ +package com.jaspersoft.mongodb.query; + +import net.sf.jasperreports.engine.JRException; +import net.sf.jasperreports.engine.query.JRQueryExecuterFactoryBundle; +import net.sf.jasperreports.engine.query.QueryExecuterFactory; +import net.sf.jasperreports.engine.util.JRSingletonCache; + +import com.jaspersoft.mongodb.MongoDbDataSource; + +/** + * + * @author Eric Diaz + * + */ +public class MongoDbQueryExecuterFactoryBundle implements + JRQueryExecuterFactoryBundle { + private static final JRSingletonCache cache = new JRSingletonCache( + QueryExecuterFactory.class); + + private static final MongoDbQueryExecuterFactoryBundle instance = new MongoDbQueryExecuterFactoryBundle(); + + private static final String[] languages = new String[] { MongoDbDataSource.QUERY_LANGUAGE }; + + private MongoDbQueryExecuterFactoryBundle() { + } + + public static MongoDbQueryExecuterFactoryBundle getInstance() { + return instance; + } + + public String[] getLanguages() { + return languages; + } + + public QueryExecuterFactory getQueryExecuterFactory(String language) + throws JRException { + if (MongoDbDataSource.QUERY_LANGUAGE.equals(language)) { + return (QueryExecuterFactory) cache + .getCachedInstance(MongoDbQueryExecuterFactory.class + .getName()); + } + return null; + } +} diff --git a/src/com/jaspersoft/mongodb/query/MongoDbQueryWrapper.java b/src/com/jaspersoft/mongodb/query/MongoDbQueryWrapper.java new file mode 100644 index 0000000..21ea00b --- /dev/null +++ b/src/com/jaspersoft/mongodb/query/MongoDbQueryWrapper.java @@ -0,0 +1,301 @@ +/******************************************************************************* + * Copyright (C) 2010 - 2013 Jaspersoft Corporation. All rights reserved. + * http://www.jaspersoft.com + * + * Unless you have purchased a commercial license agreement from Jaspersoft, + * the following license terms apply: + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Jaspersoft Studio Team - initial API and implementation + ******************************************************************************/ +package com.jaspersoft.mongodb.query; + +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.regex.Pattern; + +import net.sf.jasperreports.engine.JRException; + +import org.apache.log4j.Logger; + +import com.jaspersoft.mongodb.connection.MongoDbConnection; +import com.mongodb.BasicDBObject; +import com.mongodb.CommandResult; +import com.mongodb.DBCollection; +import com.mongodb.DBCursor; +import com.mongodb.DBObject; +import com.mongodb.MapReduceCommand; +import com.mongodb.MapReduceCommand.OutputType; +import com.mongodb.MapReduceOutput; +import com.mongodb.util.JSON; + +/** + * + * @author Eric Diaz + * + */ +public class MongoDbQueryWrapper { + private final static Logger logger = Logger.getLogger(MongoDbQueryWrapper.class); + + public static final String FIND_QUERY_KEY = "findQuery"; + + public static final String FIND_QUERY_REGEXP_KEY = "findQueryRegEx"; + + public static final String FIND_FIELDS_KEY = "findFields"; + + public static final String SORT_KEY = "sort"; + + public static final String LIMIT_KEY = "limit"; + + public static final String COLLECTION_NAME_KEY = "collectionName"; + + public static final String ROWS_TO_PROCESS_KEY = "rowsToProcess"; + + public static final String MAP_REDUCE_KEY = "mapReduce"; + + public static final String MAP_KEY = "map"; + + public static final String REDUCE_KEY = "reduce"; + + public static final String OUT_KEY = "out"; + + private static final String OUT_DB_KEY = "db"; + + private static final String FINALIZE_KEY = "finalize"; + + private static final String RUN_COMMAND_KEY = "runCommand"; + + private static final String RESULT_KEY = "result"; + + public DBCursor iterator; + + public DBObject queryObject; + + public int rowsToProcess = 5; + + private MongoDbConnection connection; + + private Map parameters; + + public List commandResults; + + public MongoDbQueryWrapper(String queryString, MongoDbConnection connection, Map parameters) + throws JRException { + this.connection = connection; + this.parameters = parameters; + processQuery(queryString); + } + + public void processQuery(String queryString) throws JRException { + logger.info("Processing mongoDB query"); + if (queryString.startsWith("\"")) { + queryString = queryString.substring(1, queryString.length()); + } + if (queryString.endsWith("\"")) { + queryString = queryString.substring(0, queryString.length() - 1); + } + Object parseResult = JSON.parse(queryString); + if (logger.isDebugEnabled()) { + logger.debug("Query: " + queryString); + } + if (!(parseResult instanceof DBObject)) { + throw new JRException("Unsupported type: " + parseResult.getClass().getName()); + } + queryObject = (DBObject) parseResult; + fixQueryObject(queryObject, parameters); + + if (queryObject.containsField(RUN_COMMAND_KEY)) { + runCommand(queryObject.removeField(RUN_COMMAND_KEY)); + } else { + createIterator(); + } + + if (queryObject.containsField(ROWS_TO_PROCESS_KEY)) { + Integer value = processInteger(queryObject.get(ROWS_TO_PROCESS_KEY)); + if (value != null) { + rowsToProcess = value.intValue(); + } + } + if (rowsToProcess == 0) { + rowsToProcess = Integer.MAX_VALUE; + } + } + + private Object fixQueryObject(DBObject queryObjectToFix, Map reportParameters) { + Set keySet = queryObjectToFix.keySet(); + if (keySet.size() == 1) { + String key = keySet.iterator().next(); + if (reportParameters.containsKey(key) && queryObjectToFix.get(key) == null) { + return reportParameters.get(key); + } + } + for (String key : queryObjectToFix.keySet()) { + Object value = queryObjectToFix.get(key); + if (value instanceof DBObject) { + queryObjectToFix.put(key, fixQueryObject((DBObject) value, reportParameters)); + } + } + return queryObjectToFix; + } + + private void runCommand(Object commandValue) throws JRException { + if (!(commandValue instanceof DBObject)) { + throw new JRException("Command must be a valid BSON object"); + } + DBObject commandObject = (DBObject) commandValue; + if (logger.isDebugEnabled()) { + logger.debug("Command object: " + commandObject); + } + CommandResult commandResult = connection.getMongoDatabase().command(commandObject); + if (!commandResult.ok()) { + throw new JRException(commandResult.getErrorMessage()); + } + Object resultObject = commandResult.get(RESULT_KEY); + if (resultObject == null) { + throw new JRException("No results"); + } + commandResults = (List) resultObject; + if (logger.isDebugEnabled()) { + logger.debug("Result List: " + resultObject); + } + } + + private void createIterator() throws JRException { + if (!queryObject.containsField(COLLECTION_NAME_KEY)) { + throw new JRException("\"" + COLLECTION_NAME_KEY + "\" must be part of the query object"); + } + DBObject findQueryObject = (DBObject) queryObject.get(FIND_QUERY_KEY); + if (findQueryObject == null) { + findQueryObject = new BasicDBObject(); + } + if (queryObject.containsField(FIND_QUERY_REGEXP_KEY)) { + DBObject regExpObject = (DBObject) queryObject.get(FIND_QUERY_REGEXP_KEY); + String value, flags; + int index; + for (String key : regExpObject.keySet()) { + value = (String) regExpObject.get(key); + if (value.startsWith("/")) { + value = value.substring(1, value.length()); + } else { + throw new JRException("Regular expressions must start with: /"); + } + if (!value.contains("/")) { + throw new JRException("No ending symbol found: /"); + } + index = value.lastIndexOf("/"); + flags = null; + if (index == value.length() - 1) { + value = value.substring(0, index); + } else { + flags = value.substring(index + 1, value.length()); + value = value.substring(0, index); + } + findQueryObject.put(key, Pattern.compile((flags != null ? "(?" + flags + ")" : "") + value)); + } + } + + DBCollection collection = connection.getMongoDatabase().getCollectionFromString( + (String) queryObject.removeField(COLLECTION_NAME_KEY)); + if (queryObject.containsField(MAP_REDUCE_KEY)) { + Object value = queryObject.removeField(MAP_REDUCE_KEY); + if (!(value instanceof DBObject)) { + logger.error("MapReduce value must be a valid JSON object"); + } else { + DBObject mapReduceObject = (DBObject) value; + String map = validateProperty(mapReduceObject, MAP_KEY); + String reduce = validateProperty(mapReduceObject, REDUCE_KEY); + Object outObject = mapReduceObject.get(OUT_KEY); + if (outObject == null) { + throw new JRException("\"out\" cannot be null"); + } + String collectionName = null; + Object outDb = null; + OutputType outputType = null; + boolean hasOutputType = false; + if (logger.isDebugEnabled()) { + logger.debug("Out object: " + outObject + ". Type: " + outObject.getClass().getName()); + } + if (outObject instanceof String) { + collectionName = String.valueOf(outObject); + } else if (outObject instanceof DBObject) { + DBObject outDbObject = (DBObject) outObject; + outDb = outDbObject.removeField(OUT_DB_KEY); + Iterator keysIterator = outDbObject.keySet().iterator(); + String type = null; + if (keysIterator.hasNext()) { + type = keysIterator.next(); + collectionName = String.valueOf(outDbObject.get(type)); + } else { + throw new JRException("\"out\" object cannot be empty"); + } + type = type.toUpperCase(); + outputType = OutputType.valueOf(type); + if (outputType == null) { + throw new JRException("Unknow output type: " + type); + } + hasOutputType = true; + if (logger.isDebugEnabled()) { + logger.debug("outobject: " + outDbObject); + logger.debug("collectionName: " + collectionName); + logger.debug("outputType: " + outputType); + } + } else { + throw new JRException("Unsupported type for \"out\": " + outObject.getClass().getName()); + } + MapReduceCommand mapReduceCommand = new MapReduceCommand(collection, map, reduce, collectionName, + hasOutputType ? outputType : OutputType.REPLACE, null); + if (outDb != null) { + mapReduceCommand.setOutputDB(String.valueOf(outDb)); + } + Object finalizeObject = mapReduceObject.removeField(FINALIZE_KEY); + if (finalizeObject != null) { + mapReduceCommand.setFinalize(String.valueOf(finalizeObject)); + } + MapReduceOutput mapReduceOutput = collection.mapReduce(mapReduceCommand); + DBCollection mapReduceCollection = mapReduceOutput.getOutputCollection(); + if (mapReduceCollection != null) { + collection = mapReduceCollection; + } + } + } + + iterator = collection.find(findQueryObject, (DBObject) queryObject.get(FIND_FIELDS_KEY)); + if (queryObject.containsField(SORT_KEY)) { + iterator = iterator.sort((DBObject) queryObject.get(SORT_KEY)); + } + if (queryObject.containsField(LIMIT_KEY)) { + Integer value = processInteger(queryObject.get(LIMIT_KEY)); + if (value != null) { + iterator = iterator.limit(value.intValue()); + } + } + } + + private Integer processInteger(Object value) { + try { + if (value instanceof Integer) { + return (Integer) value; + } else { + return Integer.parseInt((String) value); + } + } catch (Exception e) { + logger.error(e); + } + return null; + } + + public String validateProperty(DBObject object, String name) throws JRException { + Object value = object.get(name); + if (value == null) { + throw new JRException(name + " can't be null"); + } + return String.valueOf(value); + } +} diff --git a/src/com/jaspersoft/studio/data/mongodb/Activator.java b/src/com/jaspersoft/studio/data/mongodb/Activator.java new file mode 100644 index 0000000..ad83a90 --- /dev/null +++ b/src/com/jaspersoft/studio/data/mongodb/Activator.java @@ -0,0 +1,80 @@ +/******************************************************************************* + * Copyright (C) 2010 - 2013 Jaspersoft Corporation. All rights reserved. + * http://www.jaspersoft.com + * + * Unless you have purchased a commercial license agreement from Jaspersoft, + * the following license terms apply: + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Jaspersoft Studio Team - initial API and implementation + ******************************************************************************/ +package com.jaspersoft.studio.data.mongodb; + +import net.sf.jasperreports.eclipse.AbstractJRUIPlugin; + +import org.osgi.framework.BundleContext; + +/* + * The activator class controls the plug-in life cycle + */ +public class Activator extends AbstractJRUIPlugin { + + // The plug-in ID + public static final String PLUGIN_ID = "com.jaspersoft.studio.data.mongodb"; //$NON-NLS-1$ + + public static final String ICON_NAME = "icons/mongodb.png"; + + // The shared instance + private static Activator plugin; + + /** + * The constructor + */ + public Activator() { + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext + * ) + */ + @Override + public void start(BundleContext context) throws Exception { + super.start(context); + plugin = this; + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext + * ) + */ + @Override + public void stop(BundleContext context) throws Exception { + plugin = null; + super.stop(context); + } + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static Activator getDefault() { + return plugin; + } + + @Override + public String getPluginID() { + return PLUGIN_ID; + } +} diff --git a/src/com/jaspersoft/studio/data/mongodb/MongoDBIconDescriptor.java b/src/com/jaspersoft/studio/data/mongodb/MongoDBIconDescriptor.java new file mode 100644 index 0000000..fb4c817 --- /dev/null +++ b/src/com/jaspersoft/studio/data/mongodb/MongoDBIconDescriptor.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright (C) 2010 - 2013 Jaspersoft Corporation. All rights reserved. + * http://www.jaspersoft.com + * + * Unless you have purchased a commercial license agreement from Jaspersoft, + * the following license terms apply: + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Jaspersoft Studio Team - initial API and implementation + ******************************************************************************/ +package com.jaspersoft.studio.data.mongodb; + +import java.util.ResourceBundle; + +import com.jaspersoft.studio.model.util.NodeIconDescriptor; + +/* + * The Class NodeIconDescriptor. + * + * @author Chicu Veaceslav + */ +public class MongoDBIconDescriptor extends NodeIconDescriptor { + + /** + * Instantiates a new node icon descriptor. + * + * @param name + * the name + */ + public MongoDBIconDescriptor(String name) { + super(name, Activator.getDefault()); + } + + /** The resource bundle icons. */ + private static ResourceBundle resourceBundleIcons; + + @Override + public ResourceBundle getResourceBundleIcons() { + return resourceBundleIcons; + } + + @Override + public void setResourceBundleIcons(ResourceBundle resourceBundleIcons) { + MongoDBIconDescriptor.resourceBundleIcons = resourceBundleIcons; + } +} diff --git a/src/com/jaspersoft/studio/data/mongodb/MongoDBWizardDataEditorComposite.java b/src/com/jaspersoft/studio/data/mongodb/MongoDBWizardDataEditorComposite.java new file mode 100644 index 0000000..5ddb55b --- /dev/null +++ b/src/com/jaspersoft/studio/data/mongodb/MongoDBWizardDataEditorComposite.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (C) 2010 - 2013 Jaspersoft Corporation. All rights reserved. + * http://www.jaspersoft.com + * + * Unless you have purchased a commercial license agreement from Jaspersoft, + * the following license terms apply: + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Jaspersoft Studio Team - initial API and implementation + ******************************************************************************/ +package com.jaspersoft.studio.data.mongodb; + +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.swt.widgets.Composite; + +import com.jaspersoft.mongodb.MongoDbDataSource; +import com.jaspersoft.studio.data.mongodb.querydesigner.MongoDBLineStyler; +import com.jaspersoft.studio.data.ui.SimpleQueryWizardDataEditorComposite; + +public class MongoDBWizardDataEditorComposite extends + SimpleQueryWizardDataEditorComposite { + + private MongoDBLineStyler lineStyler = new MongoDBLineStyler(); + + public MongoDBWizardDataEditorComposite(Composite parent, WizardPage page, + MongoDbDataAdapterDescriptor dataAdapterDescriptor) { + super(parent, page); + setQueryLanguage(MongoDbDataSource.QUERY_LANGUAGE); + setTitle("Insert a MongoDB query and press Next"); + + this.setDataAdapterDescriptor(dataAdapterDescriptor); + + styledText.addLineStyleListener(lineStyler); + } + +} diff --git a/src/com/jaspersoft/studio/data/mongodb/MongoDbDataAdapterComposite.java b/src/com/jaspersoft/studio/data/mongodb/MongoDbDataAdapterComposite.java new file mode 100644 index 0000000..931b462 --- /dev/null +++ b/src/com/jaspersoft/studio/data/mongodb/MongoDbDataAdapterComposite.java @@ -0,0 +1,103 @@ +/******************************************************************************* + * Copyright (C) 2010 - 2013 Jaspersoft Corporation. All rights reserved. + * http://www.jaspersoft.com + * + * Unless you have purchased a commercial license agreement from Jaspersoft, + * the following license terms apply: + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Jaspersoft Studio Team - initial API and implementation + ******************************************************************************/ +package com.jaspersoft.studio.data.mongodb; + +import net.sf.jasperreports.data.DataAdapter; + +import org.eclipse.core.databinding.beans.PojoObservables; +import org.eclipse.jface.databinding.swt.SWTObservables; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Text; + +import com.jaspersoft.mongodb.adapter.MongoDbDataAdapter; +import com.jaspersoft.studio.data.ADataAdapterComposite; +import com.jaspersoft.studio.data.DataAdapterDescriptor; + +/** + * + * @author Eric Diaz + * + */ +public class MongoDbDataAdapterComposite extends ADataAdapterComposite { + private Text mongoUriField; + + private Text usernameField; + + private Text passwordField; + + private MongoDbDataAdapterDescriptor dataAdapterDescriptor; + + public MongoDbDataAdapterComposite(Composite parent, int style) { + super(parent, style); + initComponents(); + } + + private void initComponents() { + setLayout(new GridLayout(2, false)); + + createLabel("Mongo URI"); + mongoUriField = createTextField(false); + createLabel("Username"); + usernameField = createTextField(false); + createLabel("Password"); + passwordField = createTextField(true); + } + + private void createLabel(String text) { + Label label = new Label(this, SWT.NONE); + label.setText(text); + label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1)); + } + + private Text createTextField(boolean password) { + Text textField = new Text(this, !password ? SWT.BORDER : SWT.BORDER | SWT.PASSWORD); + textField.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); + return textField; + } + + public DataAdapterDescriptor getDataAdapter() { + if (dataAdapterDescriptor == null) { + dataAdapterDescriptor = new MongoDbDataAdapterDescriptor(); + } + return dataAdapterDescriptor; + } + + @Override + public void setDataAdapter(DataAdapterDescriptor dataAdapterDescriptor) { + this.dataAdapterDescriptor = (MongoDbDataAdapterDescriptor) dataAdapterDescriptor; + MongoDbDataAdapter dataAdapter = (MongoDbDataAdapter) dataAdapterDescriptor.getDataAdapter(); + bindWidgets(dataAdapter); + } + + @Override + protected void bindWidgets(DataAdapter dataAdapter) { + bindingContext.bindValue(SWTObservables.observeText(mongoUriField, SWT.Modify), + PojoObservables.observeValue(dataAdapter, "mongoURI")); + bindingContext.bindValue(SWTObservables.observeText(usernameField, SWT.Modify), + PojoObservables.observeValue(dataAdapter, "username")); + bindingContext.bindValue(SWTObservables.observeText(passwordField, SWT.Modify), + PojoObservables.observeValue(dataAdapter, "password")); + } + + @Override + public String getHelpContextId() { + return PREFIX.concat("adapter_mongodb"); + } +} diff --git a/src/com/jaspersoft/studio/data/mongodb/MongoDbDataAdapterDescriptor.java b/src/com/jaspersoft/studio/data/mongodb/MongoDbDataAdapterDescriptor.java new file mode 100644 index 0000000..2b972dd --- /dev/null +++ b/src/com/jaspersoft/studio/data/mongodb/MongoDbDataAdapterDescriptor.java @@ -0,0 +1,95 @@ +/******************************************************************************* + * Copyright (C) 2010 - 2013 Jaspersoft Corporation. All rights reserved. + * http://www.jaspersoft.com + * + * Unless you have purchased a commercial license agreement from Jaspersoft, + * the following license terms apply: + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Jaspersoft Studio Team - initial API and implementation + ******************************************************************************/ +package com.jaspersoft.studio.data.mongodb; + +import java.util.List; + +import net.sf.jasperreports.data.DataAdapter; +import net.sf.jasperreports.data.DataAdapterService; +import net.sf.jasperreports.engine.JRDataset; +import net.sf.jasperreports.engine.JRException; +import net.sf.jasperreports.engine.design.JRDesignField; + +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Composite; + +import com.jaspersoft.mongodb.adapter.MongoDbDataAdapter; +import com.jaspersoft.mongodb.adapter.MongoDbDataAdapterImplementation; +import com.jaspersoft.studio.data.AWizardDataEditorComposite; +import com.jaspersoft.studio.data.DataAdapterDescriptor; +import com.jaspersoft.studio.data.IWizardDataEditorProvider; +import com.jaspersoft.studio.data.fields.IFieldsProvider; +import com.jaspersoft.studio.utils.jasper.JasperReportsConfiguration; + +/** + * + * @author gtoffoli + * @author Eric Diaz + * + */ +public class MongoDbDataAdapterDescriptor extends DataAdapterDescriptor + implements IFieldsProvider, IWizardDataEditorProvider { + private MongoDbDataAdapter dataAdapter = new MongoDbDataAdapterImplementation(); + + private IFieldsProvider fieldsProvider; + + @Override + public MongoDbDataAdapter getDataAdapter() { + return dataAdapter; + } + + @Override + public void setDataAdapter(DataAdapter dataAdapter) { + this.dataAdapter = (MongoDbDataAdapter) dataAdapter; + } + + @Override + public MongoDbDataAdapterEditor getEditor() { + return new MongoDbDataAdapterEditor(); + } + + @Override + public Image getIcon(int size) { + if (size == 16) { + return Activator.getDefault().getImage(Activator.ICON_NAME); + } + return null; + } + + public List getFields(DataAdapterService con, + JasperReportsConfiguration jConfig, JRDataset reportDataset) + throws JRException, UnsupportedOperationException { + getFieldProvider(); + return fieldsProvider.getFields(con, jConfig, reportDataset); + } + + private void getFieldProvider() { + if (fieldsProvider == null) + fieldsProvider = new MongoDbFieldsProvider(); + } + + public boolean supportsGetFieldsOperation(JasperReportsConfiguration jConfig) { + getFieldProvider(); + return fieldsProvider.supportsGetFieldsOperation(jConfig); + } + + @Override + public AWizardDataEditorComposite createDataEditorComposite( + Composite parent, WizardPage page) { + return new MongoDBWizardDataEditorComposite(parent, page, this); + } +} diff --git a/src/com/jaspersoft/studio/data/mongodb/MongoDbDataAdapterEditor.java b/src/com/jaspersoft/studio/data/mongodb/MongoDbDataAdapterEditor.java new file mode 100644 index 0000000..2948365 --- /dev/null +++ b/src/com/jaspersoft/studio/data/mongodb/MongoDbDataAdapterEditor.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (C) 2010 - 2013 Jaspersoft Corporation. All rights reserved. + * http://www.jaspersoft.com + * + * Unless you have purchased a commercial license agreement from Jaspersoft, + * the following license terms apply: + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Jaspersoft Studio Team - initial API and implementation + ******************************************************************************/ +package com.jaspersoft.studio.data.mongodb; + +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.swt.widgets.Composite; + +import com.jaspersoft.studio.data.ADataAdapterComposite; +import com.jaspersoft.studio.data.DataAdapterDescriptor; +import com.jaspersoft.studio.data.DataAdapterEditor; + +/** + * + * @author gtoffoli + * + */ +public class MongoDbDataAdapterEditor implements DataAdapterEditor { + + protected MongoDbDataAdapterComposite composite = null; + + public ADataAdapterComposite getComposite(Composite parent, int style, WizardPage wizardPage) { + if (composite == null) + composite = new MongoDbDataAdapterComposite(parent, style); + return composite; + } + + /* + * (non-Javadoc) + * + * @see com.jaspersoft.studio.data.DataAdapterEditor#getDataAdapter() + */ + public DataAdapterDescriptor getDataAdapter() { + return composite.getDataAdapter(); + } + + /* + * (non-Javadoc) + * + * @see com.jaspersoft.studio.data.DataAdapterEditor#getHelpContextId() + */ + public String getHelpContextId() { + return composite.getHelpContextId(); + } + + /* + * (non-Javadoc) + * + * @see + * com.jaspersoft.studio.data.DataAdapterEditor#setDataAdapter(com.jaspersoft + * .studio.data.DataAdapter) + */ + public void setDataAdapter(DataAdapterDescriptor dataAdapter) { + if (dataAdapter instanceof MongoDbDataAdapterDescriptor) + composite.setDataAdapter((MongoDbDataAdapterDescriptor) dataAdapter); + } +} diff --git a/src/com/jaspersoft/studio/data/mongodb/MongoDbDataAdapterFactory.java b/src/com/jaspersoft/studio/data/mongodb/MongoDbDataAdapterFactory.java new file mode 100644 index 0000000..ce7d877 --- /dev/null +++ b/src/com/jaspersoft/studio/data/mongodb/MongoDbDataAdapterFactory.java @@ -0,0 +1,94 @@ +/******************************************************************************* + * Copyright (C) 2010 - 2013 Jaspersoft Corporation. All rights reserved. + * http://www.jaspersoft.com + * + * Unless you have purchased a commercial license agreement from Jaspersoft, + * the following license terms apply: + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Jaspersoft Studio Team - initial API and implementation + ******************************************************************************/ +package com.jaspersoft.studio.data.mongodb; + +import net.sf.jasperreports.data.DataAdapter; +import net.sf.jasperreports.data.DataAdapterService; + +import org.eclipse.swt.graphics.Image; + +import com.jaspersoft.mongodb.adapter.MongoDbDataAdapter; +import com.jaspersoft.mongodb.adapter.MongoDbDataAdapterImplementation; +import com.jaspersoft.mongodb.adapter.MongoDbDataAdapterService; +import com.jaspersoft.studio.data.DataAdapterDescriptor; +import com.jaspersoft.studio.data.DataAdapterFactory; +import com.jaspersoft.studio.data.mongodb.messages.Messages; + +/** + * @author gtoffoli + * + */ +public class MongoDbDataAdapterFactory implements DataAdapterFactory { + + /* + * (non-Javadoc) + * + * @see com.jaspersoft.studio.data.DataAdapterFactory#createDataAdapter() + */ + public DataAdapterDescriptor createDataAdapter() { + MongoDbDataAdapterDescriptor descriptor = new MongoDbDataAdapterDescriptor(); + descriptor.getDataAdapter().setMongoURI("mongodb://HOST:27017/DB_NAME"); //$NON-NLS-1$ + descriptor.getDataAdapter().setUsername(""); //$NON-NLS-1$ + descriptor.getDataAdapter().setPassword(""); //$NON-NLS-1$ + return descriptor; + } + + /* + * (non-Javadoc) + * + * @see + * com.jaspersoft.studio.data.DataAdapterFactory#getDataAdapterClassName() + */ + public String getDataAdapterClassName() { + return MongoDbDataAdapterImplementation.class.getName(); + } + + /* + * (non-Javadoc) + * + * @see com.jaspersoft.studio.data.DataAdapterFactory#getDescription() + */ + public String getLabel() { + return Messages.MongoDbDataAdapterFactory_label; + } + + /* + * (non-Javadoc) + * + * @see com.jaspersoft.studio.data.DataAdapterFactory#getDescription() + */ + public String getDescription() { + return Messages.MongoDbDataAdapterFactory_description; + } + + /* + * (non-Javadoc) + * + * @see com.jaspersoft.studio.data.DataAdapterFactory#getIcon(int) + */ + public Image getIcon(int size) { + if (size == 16) { + return Activator.getDefault().getImage(Activator.ICON_NAME); + } + return null; + } + + public DataAdapterService createDataAdapterService(DataAdapter dataAdapter) { + if (dataAdapter instanceof MongoDbDataAdapter) + return new MongoDbDataAdapterService((MongoDbDataAdapter) dataAdapter); + return null; + } +} diff --git a/src/com/jaspersoft/studio/data/mongodb/MongoDbFieldsProvider.java b/src/com/jaspersoft/studio/data/mongodb/MongoDbFieldsProvider.java new file mode 100644 index 0000000..bf588f0 --- /dev/null +++ b/src/com/jaspersoft/studio/data/mongodb/MongoDbFieldsProvider.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright (C) 2010 - 2013 Jaspersoft Corporation. All rights reserved. + * http://www.jaspersoft.com + * + * Unless you have purchased a commercial license agreement from Jaspersoft, + * the following license terms apply: + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Jaspersoft Studio Team - initial API and implementation + ******************************************************************************/ +package com.jaspersoft.studio.data.mongodb; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import net.sf.jasperreports.data.DataAdapterService; +import net.sf.jasperreports.engine.JRDataset; +import net.sf.jasperreports.engine.JRException; +import net.sf.jasperreports.engine.JRParameter; +import net.sf.jasperreports.engine.design.JRDesignField; + +import com.jaspersoft.mongodb.connection.MongoDbConnection; +import com.jaspersoft.studio.data.fields.IFieldsProvider; +import com.jaspersoft.studio.utils.jasper.JasperReportsConfiguration; +import com.jaspersoft.studio.utils.parameter.ParameterUtil; + +/** + * + * @author Eric Diaz + * + */ +public class MongoDbFieldsProvider implements IFieldsProvider { + public boolean supportsGetFieldsOperation(JasperReportsConfiguration jConfig) { + return true; + } + + public List getFields(DataAdapterService dataAdapterService, + JasperReportsConfiguration jasperReportsConfiguration, JRDataset dataset) throws JRException, + UnsupportedOperationException { + Map parameters = new HashMap(); + parameters.put(JRParameter.REPORT_MAX_COUNT, 0); + dataAdapterService.contributeParameters(parameters); + ParameterUtil.setParameters(jasperReportsConfiguration, dataset, parameters); + + return com.jaspersoft.mongodb.MongoDbFieldsProvider.getInstance().getFields(jasperReportsConfiguration, dataset, parameters, + (MongoDbConnection) parameters.get(JRParameter.REPORT_CONNECTION)); + } +} diff --git a/src/com/jaspersoft/studio/data/mongodb/messages/Messages.java b/src/com/jaspersoft/studio/data/mongodb/messages/Messages.java new file mode 100644 index 0000000..31b2fdb --- /dev/null +++ b/src/com/jaspersoft/studio/data/mongodb/messages/Messages.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (C) 2010 - 2013 Jaspersoft Corporation. All rights reserved. + * http://www.jaspersoft.com + * + * Unless you have purchased a commercial license agreement from Jaspersoft, + * the following license terms apply: + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Jaspersoft Studio Team - initial API and implementation + ******************************************************************************/ +package com.jaspersoft.studio.data.mongodb.messages; + +import org.eclipse.osgi.util.NLS; + +public class Messages extends NLS { + private static final String BUNDLE_NAME = "com.jaspersoft.studio.data.mongodb.messages.messages"; //$NON-NLS-1$ + public static String MongoDbDataAdapterFactory_description; + public static String MongoDbDataAdapterFactory_label; + public static String RDDatasourceMongoDBPage_desc; + public static String RDDatasourceMongoDBPage_labelurl; + public static String RDDatasourceMongoDBPage_pass; + public static String RDDatasourceMongoDBPage_title; + public static String RDDatasourceMongoDBPage_username; + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } + + private Messages() { + } +} diff --git a/src/com/jaspersoft/studio/data/mongodb/messages/messages.properties b/src/com/jaspersoft/studio/data/mongodb/messages/messages.properties new file mode 100644 index 0000000..bf83a20 --- /dev/null +++ b/src/com/jaspersoft/studio/data/mongodb/messages/messages.properties @@ -0,0 +1,22 @@ +#------------------------------------------------------------------------------- +# Copyright (C) 2010 - 2013 Jaspersoft Corporation. All rights reserved. +# http://www.jaspersoft.com +# +# Unless you have purchased a commercial license agreement from Jaspersoft, +# the following license terms apply: +# +# This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Jaspersoft Studio Team - initial API and implementation +#------------------------------------------------------------------------------- +MongoDbDataAdapterFactory_description=Use MongoDbQuery queries to get data from MongoDB +MongoDbDataAdapterFactory_label=MongoDB Connection +RDDatasourceMongoDBPage_desc=MongoDB Datasource +RDDatasourceMongoDBPage_labelurl=URL +RDDatasourceMongoDBPage_pass=Password +RDDatasourceMongoDBPage_title=MongoDB Datasource +RDDatasourceMongoDBPage_username=Username diff --git a/src/com/jaspersoft/studio/data/mongodb/messages/messages_it.properties b/src/com/jaspersoft/studio/data/mongodb/messages/messages_it.properties new file mode 100644 index 0000000..92c0b94 --- /dev/null +++ b/src/com/jaspersoft/studio/data/mongodb/messages/messages_it.properties @@ -0,0 +1,22 @@ +#------------------------------------------------------------------------------- +# Copyright (C) 2010 - 2013 Jaspersoft Corporation. All rights reserved. +# http://www.jaspersoft.com +# +# Unless you have purchased a commercial license agreement from Jaspersoft, +# the following license terms apply: +# +# This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Jaspersoft Studio Team - initial API and implementation +#------------------------------------------------------------------------------- +MongoDbDataAdapterFactory_description=Usa delle query MongoDbQuery per estrarre i dati da un MongoDB +MongoDbDataAdapterFactory_label=Connessione MongoDB +RDDatasourceMongoDBPage_desc=Datasource MongoDB +RDDatasourceMongoDBPage_labelurl=URL +RDDatasourceMongoDBPage_pass=Password +RDDatasourceMongoDBPage_title=Datasource MongoDB +RDDatasourceMongoDBPage_username=Username diff --git a/src/com/jaspersoft/studio/data/mongodb/querydesigner/JsonTokensType.java b/src/com/jaspersoft/studio/data/mongodb/querydesigner/JsonTokensType.java new file mode 100644 index 0000000..d0887eb --- /dev/null +++ b/src/com/jaspersoft/studio/data/mongodb/querydesigner/JsonTokensType.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (C) 2010 - 2013 Jaspersoft Corporation. All rights reserved. + * http://www.jaspersoft.com + * + * Unless you have purchased a commercial license agreement from Jaspersoft, + * the following license terms apply: + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Jaspersoft Studio Team - initial API and implementation + ******************************************************************************/ +package com.jaspersoft.studio.data.mongodb.querydesigner; + + +/** + * Enumeration for different types of Json Query tokens. + */ +public enum JsonTokensType { + TEXT(true),KEYWORD(true),QUOTED_LITERAL(true),NUMBER(true), + SYMBOL(true),EOF(false),EOL(false),SPACE(false),OTHER(true), + JRPARAMETER(true),JRVARIABLE(true),JRFIELD(true); + + private boolean hasColor; + + private JsonTokensType(boolean hasColor) { + this.hasColor=hasColor; + } + + public static int getColoredTokensNum(){ + int num=0; + for (JsonTokensType t : values()){ + if(t.hasColor){ + num++; + } + } + return num; + } +} diff --git a/src/com/jaspersoft/studio/data/mongodb/querydesigner/MongoDBLineStyler.java b/src/com/jaspersoft/studio/data/mongodb/querydesigner/MongoDBLineStyler.java new file mode 100644 index 0000000..b5b4aa1 --- /dev/null +++ b/src/com/jaspersoft/studio/data/mongodb/querydesigner/MongoDBLineStyler.java @@ -0,0 +1,127 @@ +/******************************************************************************* + * Copyright (C) 2010 - 2013 Jaspersoft Corporation. All rights reserved. + * http://www.jaspersoft.com + * + * Unless you have purchased a commercial license agreement from Jaspersoft, + * the following license terms apply: + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Jaspersoft Studio Team - initial API and implementation + ******************************************************************************/ +package com.jaspersoft.studio.data.mongodb.querydesigner; + +import java.util.HashMap; +import java.util.Map; +import java.util.Vector; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.LineStyleEvent; +import org.eclipse.swt.custom.LineStyleListener; +import org.eclipse.swt.custom.StyleRange; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.widgets.Control; +import org.eclipse.wb.swt.ResourceManager; + +/** + * This class provides the style information for the MongoDB query text (JSON based) line being drawn. + *

+ * NOTE: Re-used code and idea from JavaViewer SWT Example. + * + * @see MongoDBScanner + * + */ +public class MongoDBLineStyler implements LineStyleListener { + + private MongoDBScanner jsonScanner; + private Map colorsMap; + + public MongoDBLineStyler(){ + initializeColors(); + jsonScanner=new MongoDBScanner(); + } + + private void initializeColors() { + colorsMap=new HashMap(JsonTokensType.getColoredTokensNum()); + colorsMap.put(JsonTokensType.TEXT, ResourceManager.getColor(0, 0, 0)); + colorsMap.put(JsonTokensType.KEYWORD, ResourceManager.getColor(196, 58, 34)); + colorsMap.put(JsonTokensType.QUOTED_LITERAL, ResourceManager.getColor(15,128,0)); + colorsMap.put(JsonTokensType.SYMBOL, ResourceManager.getColor(0, 0, 0)); + colorsMap.put(JsonTokensType.OTHER, ResourceManager.getColor(0, 0, 0)); + colorsMap.put(JsonTokensType.NUMBER, ResourceManager.getColor(45, 0, 255)); + colorsMap.put(JsonTokensType.JRPARAMETER,ResourceManager.getColor(178, 0, 0)); + colorsMap.put(JsonTokensType.JRFIELD,ResourceManager.getColor(32,187,34)); + colorsMap.put(JsonTokensType.JRVARIABLE,ResourceManager.getColor(17,18,254)); + } + + /* + * Gets the right color for the specified token type. + */ + private Color getColor(JsonTokensType type){ + if(type!=null){ + return colorsMap.get(type); + } + return null; + } + + @Override + public void lineGetStyle(LineStyleEvent event) { + Vector styles=new Vector(); + JsonTokensType token=null; + StyleRange lastStyle=null; + + Color defaultFgColor = ((Control) event.widget).getForeground(); + jsonScanner.setRange(event.lineText); + token = jsonScanner.nextToken(); + while (token != JsonTokensType.EOF) { + if (token == JsonTokensType.OTHER) { + // do nothing for non-colored tokens + } else if (token != JsonTokensType.SPACE) { + Color color = getColor(token); + // Only create a style if the token color is different than the + // widget's default foreground color and the token's style is not bold. + // Keywords, symbols and operators are drawn bold. + if (!color.equals(defaultFgColor) || (token == JsonTokensType.SYMBOL)) { + StyleRange style = new StyleRange(jsonScanner.getStartOffset() + + event.lineOffset, jsonScanner.getLength(), color, + null); + if (token==JsonTokensType.SYMBOL) { + style.fontStyle = SWT.BOLD; + } + if (styles.isEmpty()) { + styles.addElement(style); + } else { + // Merge similar styles. Doing so will improve performance. + lastStyle = (StyleRange) styles.lastElement(); + if (lastStyle.similarTo(style) + && (lastStyle.start + lastStyle.length == style.start)) { + lastStyle.length += style.length; + } else { + styles.addElement(style); + } + } + } + } else if ((!styles.isEmpty()) + && ((lastStyle = (StyleRange) styles.lastElement()).fontStyle == SWT.BOLD)) { + int start = jsonScanner.getStartOffset() + event.lineOffset; + lastStyle = (StyleRange) styles.lastElement(); + // A font style of SWT.BOLD implies that the last style + // represents a java keyword. + if (lastStyle.start + lastStyle.length == start) { + // Have the white space take on the style before it to + // minimize the number of style ranges created and the + // number of font style changes during rendering. + lastStyle.length += jsonScanner.getLength(); + } + } + token = jsonScanner.nextToken(); + } + event.styles = new StyleRange[styles.size()]; + styles.copyInto(event.styles); + + } +} diff --git a/src/com/jaspersoft/studio/data/mongodb/querydesigner/MongoDBQueryDesigner.java b/src/com/jaspersoft/studio/data/mongodb/querydesigner/MongoDBQueryDesigner.java new file mode 100644 index 0000000..ac5e05c --- /dev/null +++ b/src/com/jaspersoft/studio/data/mongodb/querydesigner/MongoDBQueryDesigner.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright (C) 2010 - 2013 Jaspersoft Corporation. All rights reserved. + * http://www.jaspersoft.com + * + * Unless you have purchased a commercial license agreement from Jaspersoft, + * the following license terms apply: + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Jaspersoft Studio Team - initial API and implementation + ******************************************************************************/ +package com.jaspersoft.studio.data.mongodb.querydesigner; + +import net.sf.jasperreports.engine.design.JRDesignQuery; + +import org.eclipse.swt.custom.StyledText; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; + +import com.jaspersoft.studio.data.designer.QueryDesigner; +import com.jaspersoft.studio.wizards.ContextHelpIDs; + +/** + * Simple query designer for MongoDB query language that provides syntax + * highlighting. + * + */ +public class MongoDBQueryDesigner extends QueryDesigner { + /* Text area where enter the query */ + protected StyledText queryTextArea; + private MongoDBLineStyler lineStyler = new MongoDBLineStyler(); + + public Control createControl(Composite parent) { + control = (StyledText) super.createControl(parent); + control.addLineStyleListener(lineStyler); + return control; + } + + protected void queryTextAreaModified() { + // keep the query info updated + ((JRDesignQuery) jDataset.getQuery()).setText(queryTextArea.getText()); + } + + @Override + public String getContextHelpId() { + return ContextHelpIDs.PREFIX.concat("query_mongo"); + } +} diff --git a/src/com/jaspersoft/studio/data/mongodb/querydesigner/MongoDBScanner.java b/src/com/jaspersoft/studio/data/mongodb/querydesigner/MongoDBScanner.java new file mode 100644 index 0000000..1f25563 --- /dev/null +++ b/src/com/jaspersoft/studio/data/mongodb/querydesigner/MongoDBScanner.java @@ -0,0 +1,195 @@ +/******************************************************************************* + * Copyright (C) 2010 - 2013 Jaspersoft Corporation. All rights reserved. + * http://www.jaspersoft.com + * + * Unless you have purchased a commercial license agreement from Jaspersoft, + * the following license terms apply: + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Jaspersoft Studio Team - initial API and implementation + ******************************************************************************/ +package com.jaspersoft.studio.data.mongodb.querydesigner; + +import java.util.Arrays; +import java.util.List; + + +/** + * Class implementing a simple fuzzy scanner for MongoDB query text (JSON based). + *

+ * + * NOTE: Re-used code and idea from JavaViewer SWT Example. + * + * @see MongoDBLineStyler + */ +public class MongoDBScanner { + public static final int EOF_CHAR=-1; + public static final int EOL_CHAR=10; + private static List jsonKeywords; + private static List jsonOperatorsAndSymbols; + + private StringBuffer fBuffer = new StringBuffer(); + private String fDoc; + private int fPos; + private int fEnd; + private int fStartToken; + + public MongoDBScanner(){ + initJsonKeywords(); + initJsonSymbolsAndOperators(); + } + + /** + * Gets next token type in order to decide how to "style it". + * + * @return the token type + */ + public JsonTokensType nextToken() { + int c; + fStartToken = fPos; + while (true) { + switch (c = read()) { + case EOF_CHAR: + return JsonTokensType.EOF; + case '$': + c = read(); + JsonTokensType jrbaseExprType=null; + if(c=='P'){ + jrbaseExprType=JsonTokensType.JRPARAMETER; + } + else if(c=='F'){ + jrbaseExprType=JsonTokensType.JRFIELD; + } + else if(c=='V'){ + jrbaseExprType=JsonTokensType.JRVARIABLE; + } + else { + break; + } + c = read(); + if(c=='{'){ + for (;;) { + c = read(); + switch (c) { + case '}': + return jrbaseExprType; + case EOF_CHAR: + unread(c); + return jrbaseExprType; + case '\\': + c = read(); + break; + } + } + } + case '"': + for (;;) { + c = read(); + switch (c) { + case '"': + return JsonTokensType.QUOTED_LITERAL; + case EOF_CHAR: + unread(c); + return JsonTokensType.QUOTED_LITERAL; + case '\\': + c = read(); + break; + } + } + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + do { + c = read(); + } while (Character.isDigit((char) c)); + unread(c); + return JsonTokensType.NUMBER; + default: + if (jsonOperatorsAndSymbols.contains(Character.toString((char)c))){ + return JsonTokensType.SYMBOL; + } + if (Character.isWhitespace((char) c)) { + do { + c = read(); + } while (Character.isWhitespace((char) c)); + unread(c); + return JsonTokensType.SPACE; + } + if (Character.isJavaIdentifierStart((char) c)) { + fBuffer.setLength(0); + do { + fBuffer.append((char) c); + c = read(); + } while (Character.isJavaIdentifierPart((char) c)); + unread(c); + + if(jsonKeywords.contains(fBuffer.toString().toLowerCase())){ + return JsonTokensType.KEYWORD; + } + return JsonTokensType.OTHER; + } + return JsonTokensType.OTHER; + } + } + } + + private int read() { + if (fPos <= fEnd) { + return fDoc.charAt(fPos++); + } + return EOF_CHAR; + } + + private void unread(int c) { + if (c != EOF_CHAR) + fPos--; + } + + public void setRange(String text) { + fDoc = text; + fPos = 0; + fEnd = fDoc.length() - 1; + } + + public int getStartOffset() { + return fStartToken; + } + + public int getLength() { + return fPos - fStartToken; + } + + /** + * Initializes, if needed, the Json keywords used by the scanner instance. + */ + protected void initJsonKeywords(){ + if(jsonKeywords==null){ + jsonKeywords=Arrays.asList( + new String[]{"true", "false", "null"}); + } + } + + /** + * Initializes, if needed, the Json symbols and operators used by the scanner instance. + */ + protected void initJsonSymbolsAndOperators(){ + if(jsonOperatorsAndSymbols==null){ + jsonOperatorsAndSymbols=Arrays.asList( + new String[]{"[", "]", "=", "!", ">", "<"}); + } + } + +} + diff --git a/src/com/jaspersoft/studio/data/mongodb/server/DatasourceMongoDBPageContent.java b/src/com/jaspersoft/studio/data/mongodb/server/DatasourceMongoDBPageContent.java new file mode 100644 index 0000000..d42c8c6 --- /dev/null +++ b/src/com/jaspersoft/studio/data/mongodb/server/DatasourceMongoDBPageContent.java @@ -0,0 +1,101 @@ +/******************************************************************************* + * Copyright (C) 2010 - 2013 Jaspersoft Corporation. All rights reserved. + * http://www.jaspersoft.com + * + * Unless you have purchased a commercial license agreement from Jaspersoft, + * the following license terms apply: + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Jaspersoft Studio Team - initial API and implementation + ******************************************************************************/ +package com.jaspersoft.studio.data.mongodb.server; + +import org.eclipse.core.databinding.DataBindingContext; +import org.eclipse.core.databinding.beans.PojoObservables; +import org.eclipse.jface.databinding.swt.SWTObservables; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Text; + +import com.jaspersoft.jasperserver.api.metadata.xml.domain.impl.ResourceProperty; +import com.jaspersoft.studio.data.mongodb.messages.Messages; +import com.jaspersoft.studio.model.ANode; +import com.jaspersoft.studio.server.model.MResource; +import com.jaspersoft.studio.server.model.datasource.MRDatasourceCustom; +import com.jaspersoft.studio.server.utils.ResourceDescriptorUtil; +import com.jaspersoft.studio.server.wizard.resource.APageContent; +import com.jaspersoft.studio.utils.UIUtil; + +public class DatasourceMongoDBPageContent extends APageContent { + + public DatasourceMongoDBPageContent(ANode parent, MResource resource, + DataBindingContext bindingContext) { + super(parent, resource, bindingContext); + } + + public DatasourceMongoDBPageContent(ANode parent, MResource resource) { + super(parent, resource); + } + + @Override + public String getPageName() { + return "com.jaspersoft.studio.server.page.datasource.mongodb"; + } + + @Override + public String getName() { + return Messages.RDDatasourceMongoDBPage_title; + } + + public Control createContent(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + composite.setLayout(new GridLayout(2, false)); + + UIUtil.createLabel(composite, + Messages.RDDatasourceMongoDBPage_labelurl); + + Text turi = new Text(composite, SWT.BORDER); + turi.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + UIUtil.createLabel(composite, + Messages.RDDatasourceMongoDBPage_username); + + Text tusername = new Text(composite, SWT.BORDER); + tusername.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + UIUtil.createLabel(composite, Messages.RDDatasourceMongoDBPage_pass); + + Text tpass = new Text(composite, SWT.BORDER | SWT.PASSWORD); + tpass.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + ResourceProperty resprop = ResourceDescriptorUtil.getProperty( + MRDatasourceCustom.PROP_DATASOURCE_CUSTOM_PROPERTY_MAP, res + .getValue().getProperties()); + + ResourceProperty rsp = ResourceDescriptorUtil.getProperty( + MRDatasourceMongoDB.MONGO_URI, resprop.getProperties()); + bindingContext.bindValue(SWTObservables.observeText(turi, SWT.Modify), + PojoObservables.observeValue(rsp, "value")); //$NON-NLS-1$ + + rsp = ResourceDescriptorUtil.getProperty(MRDatasourceMongoDB.USERNAME, + resprop.getProperties()); + bindingContext.bindValue( + SWTObservables.observeText(tusername, SWT.Modify), + PojoObservables.observeValue(rsp, "value")); //$NON-NLS-1$ + + rsp = ResourceDescriptorUtil.getProperty(MRDatasourceMongoDB.PASSWORD, + resprop.getProperties()); + bindingContext.bindValue(SWTObservables.observeText(tpass, SWT.Modify), + PojoObservables.observeValue(rsp, "value")); //$NON-NLS-1$ + + return composite; + } +} diff --git a/src/com/jaspersoft/studio/data/mongodb/server/MRDatasourceMongoDB.java b/src/com/jaspersoft/studio/data/mongodb/server/MRDatasourceMongoDB.java new file mode 100644 index 0000000..cb0e5d6 --- /dev/null +++ b/src/com/jaspersoft/studio/data/mongodb/server/MRDatasourceMongoDB.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * Copyright (C) 2010 - 2013 Jaspersoft Corporation. All rights reserved. + * http://www.jaspersoft.com + * + * Unless you have purchased a commercial license agreement from Jaspersoft, + * the following license terms apply: + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Jaspersoft Studio Team - initial API and implementation + ******************************************************************************/ +package com.jaspersoft.studio.data.mongodb.server; + +import java.util.ArrayList; +import java.util.List; + +import net.sf.jasperreports.engine.JRConstants; + +import com.jaspersoft.jasperserver.api.metadata.xml.domain.impl.ResourceDescriptor; +import com.jaspersoft.jasperserver.api.metadata.xml.domain.impl.ResourceProperty; +import com.jaspersoft.studio.data.mongodb.MongoDBIconDescriptor; +import com.jaspersoft.studio.model.ANode; +import com.jaspersoft.studio.model.util.IIconDescriptor; +import com.jaspersoft.studio.server.model.datasource.MRDatasourceCustom; + +public class MRDatasourceMongoDB extends MRDatasourceCustom { + + public static final String PASSWORD = "password"; + public static final String MONGO_URI = "mongoURI"; + public static final String USERNAME = "username"; + public static final String CUSTOM_CLASS = "com.jaspersoft.mongodb.jasperserver.MongoDbDataSourceService"; + public static final long serialVersionUID = JRConstants.SERIAL_VERSION_UID; + + public MRDatasourceMongoDB(ANode parent, ResourceDescriptor rd, int index) { + super(parent, rd, index); + } + + private static IIconDescriptor iconDescriptor; + + public static IIconDescriptor getIconDescriptor() { + if (iconDescriptor == null) + iconDescriptor = new MongoDBIconDescriptor("datasource-mongo"); //$NON-NLS-1$ + return iconDescriptor; + } + + @Override + public IIconDescriptor getThisIconDescriptor() { + return getIconDescriptor(); + } + + public static ResourceDescriptor createDescriptor(ANode parent) { + ResourceDescriptor rd = MRDatasourceCustom.createDescriptor(parent); + ResourceProperty rp = new ResourceProperty( + MRDatasourceCustom.PROP_DATASOURCE_CUSTOM_PROPERTY_MAP); + List props = new ArrayList(); + props.add(new ResourceProperty(USERNAME, USERNAME)); + props.add(new ResourceProperty(MONGO_URI, + "mongodb://hostname:27017/database")); + props.add(new ResourceProperty("_cds_name", "MongoDbDataSource")); + props.add(new ResourceProperty(PASSWORD, PASSWORD)); + rp.setProperties(props); + rd.getProperties().add(rp); + rp = new ResourceProperty( + MRDatasourceCustom.PROP_DATASOURCE_CUSTOM_SERVICE_CLASS, + CUSTOM_CLASS); + rd.getProperties().add(rp); + return rd; + } +} diff --git a/src/com/jaspersoft/studio/data/mongodb/server/MongoResourceFactory.java b/src/com/jaspersoft/studio/data/mongodb/server/MongoResourceFactory.java new file mode 100644 index 0000000..e57ae14 --- /dev/null +++ b/src/com/jaspersoft/studio/data/mongodb/server/MongoResourceFactory.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * Copyright (C) 2010 - 2013 Jaspersoft Corporation. All rights reserved. + * http://www.jaspersoft.com + * + * Unless you have purchased a commercial license agreement from Jaspersoft, + * the following license terms apply: + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Jaspersoft Studio Team - initial API and implementation + ******************************************************************************/ +package com.jaspersoft.studio.data.mongodb.server; + +import org.eclipse.jface.wizard.IWizardPage; + +import com.jaspersoft.jasperserver.api.metadata.xml.domain.impl.ResourceDescriptor; +import com.jaspersoft.jasperserver.api.metadata.xml.domain.impl.ResourceProperty; +import com.jaspersoft.studio.model.ANode; +import com.jaspersoft.studio.model.MRoot; +import com.jaspersoft.studio.server.model.MResource; +import com.jaspersoft.studio.server.model.datasource.MRDatasourceCustom; +import com.jaspersoft.studio.server.plugin.IResourceFactory; +import com.jaspersoft.studio.server.utils.ResourceDescriptorUtil; +import com.jaspersoft.studio.server.wizard.resource.APageContent; +import com.jaspersoft.studio.server.wizard.resource.page.ResourcePageContent; + +public class MongoResourceFactory implements IResourceFactory { + + public MResource getResource(ANode parent, ResourceDescriptor resource, + int index) { + if (resource.getWsType().equals( + ResourceDescriptor.TYPE_DATASOURCE_CUSTOM)) { + ResourceProperty rp = ResourceDescriptorUtil.getProperty( + MRDatasourceCustom.PROP_DATASOURCE_CUSTOM_SERVICE_CLASS, + resource.getProperties()); + if (rp != null + && rp.getValue().equals(MRDatasourceMongoDB.CUSTOM_CLASS)) + return new MRDatasourceMongoDB(parent, resource, index); + } + return null; + } + + public IWizardPage[] getResourcePage(ANode parent, MResource resource) { + if (resource instanceof MRDatasourceMongoDB) + return APageContent.getPages(resource, new ResourcePageContent( + parent, resource), new DatasourceMongoDBPageContent(parent, + resource)); + return null; + } + + public ANode createNewResource(MRoot root, ANode parent) { + return null; + } + + @Override + public ANode createNewDatasource(MRoot root, ANode parent) { + return new MRDatasourceMongoDB(root, + MRDatasourceMongoDB.createDescriptor(parent), -1); + } + +} diff --git a/src/jasperreports_extension.properties b/src/jasperreports_extension.properties new file mode 100644 index 0000000..47de59e --- /dev/null +++ b/src/jasperreports_extension.properties @@ -0,0 +1,18 @@ +#------------------------------------------------------------------------------- +# Copyright (C) 2010 - 2013 Jaspersoft Corporation. All rights reserved. +# http://www.jaspersoft.com +# +# Unless you have purchased a commercial license agreement from Jaspersoft, +# the following license terms apply: +# +# This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Jaspersoft Studio Team - initial API and implementation +#------------------------------------------------------------------------------- +net.sf.jasperreports.extension.registry.factory.repository.castor.mapping=net.sf.jasperreports.repo.CastorMappingExtensionsRegistryFactory +net.sf.jasperreports.extension.repository.castor.mapping.mongodb=com/jaspersoft/mongodb/adapter/MongoDbDataAdapterImpl.xml +net.sf.jasperreports.extension.registry.factory.queryexecuters.mongodb=com.jaspersoft.mongodb.query.MongoDbQueryExecuterExtensionsRegistryFactory diff --git a/toc_dataadapters.xml b/toc_dataadapters.xml new file mode 100644 index 0000000..1c21f93 --- /dev/null +++ b/toc_dataadapters.xml @@ -0,0 +1,8 @@ + + + + + + + +