teiid SVN: r4077 - in branches/7.7.x: client/src/main/java/org/teiid/client and 6 other directories.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2012-05-09 10:36:12 -0400 (Wed, 09 May 2012)
New Revision: 4077
Added:
branches/7.7.x/client/src/main/java/org/teiid/client/security/Secure.java
Modified:
branches/7.7.x/build/kits/jboss-container/teiid-releasenotes.html
branches/7.7.x/client/src/main/java/org/teiid/client/DQP.java
branches/7.7.x/client/src/main/java/org/teiid/client/security/ILogon.java
branches/7.7.x/client/src/main/java/org/teiid/jdbc/ConnectionImpl.java
branches/7.7.x/client/src/main/java/org/teiid/jdbc/JDBCURL.java
branches/7.7.x/client/src/main/java/org/teiid/jdbc/StatementImpl.java
branches/7.7.x/client/src/main/java/org/teiid/jdbc/TeiidDataSource.java
branches/7.7.x/client/src/main/java/org/teiid/net/TeiidURL.java
branches/7.7.x/client/src/main/java/org/teiid/net/socket/SocketServerConnection.java
branches/7.7.x/client/src/main/java/org/teiid/net/socket/SocketServerInstanceImpl.java
branches/7.7.x/client/src/test/java/org/teiid/jdbc/TestStatement.java
branches/7.7.x/client/src/test/java/org/teiid/jdbc/TestTeiidDriver.java
branches/7.7.x/documentation/client-developers-guide/src/main/docbook/en-US/content/jdbc-connection.xml
branches/7.7.x/documentation/client-developers-guide/src/main/docbook/en-US/content/jdbc-extensions.xml
Log:
TEIID-2006 back port of set payload and encrypt requests
Modified: branches/7.7.x/build/kits/jboss-container/teiid-releasenotes.html
===================================================================
--- branches/7.7.x/build/kits/jboss-container/teiid-releasenotes.html 2012-05-09 14:35:51 UTC (rev 4076)
+++ branches/7.7.x/build/kits/jboss-container/teiid-releasenotes.html 2012-05-09 14:36:12 UTC (rev 4077)
@@ -33,6 +33,8 @@
<LI><B>Padded String Comparison</B> - the system property org.teiid.padSpace can be set to effectively right pad strings to the same length for comparison.
<LI><B>Copy LOBs</B> - added the copyLobs property to indicate that lob values should be copied by the engine rather than being held by reference.
<LI><B>Enhanced parse/format pushdown</B> - added more built-in support and extension points for parse/format function pushdown. Added parse/format timestamp handling for SQLServer, Sybase, Oracle, and PostgreSQL.
+ <LI><B>SET PAYLOAD statement</B> - SET PAYLOAD can be used to set a name value pair on a session scoped payload that will be sent with requests.
+ <LI><B>ENCRYPT REQUESTS</B> - encryptRequests may be used as a connection/datasource property when not using SSL to indicate that request messgaes and any associated payload should be encrypted.
</UL>
<h2><a name="Compatibility">Compatibility Issues</a></h2>
Modified: branches/7.7.x/client/src/main/java/org/teiid/client/DQP.java
===================================================================
--- branches/7.7.x/client/src/main/java/org/teiid/client/DQP.java 2012-05-09 14:35:51 UTC (rev 4076)
+++ branches/7.7.x/client/src/main/java/org/teiid/client/DQP.java 2012-05-09 14:36:12 UTC (rev 4077)
@@ -26,6 +26,7 @@
import org.teiid.client.lob.LobChunk;
import org.teiid.client.metadata.MetadataResult;
+import org.teiid.client.security.Secure;
import org.teiid.client.util.ResultsFuture;
import org.teiid.client.xa.XATransactionException;
import org.teiid.client.xa.XidImpl;
@@ -35,6 +36,7 @@
public interface DQP {
+ @Secure(optional=true)
ResultsFuture<ResultsMessage> executeRequest(long reqID, RequestMessage message) throws TeiidProcessingException, TeiidComponentException;
ResultsFuture<ResultsMessage> processCursorRequest(long reqID, int batchFirst, int fetchSize) throws TeiidProcessingException;
Modified: branches/7.7.x/client/src/main/java/org/teiid/client/security/ILogon.java
===================================================================
--- branches/7.7.x/client/src/main/java/org/teiid/client/security/ILogon.java 2012-05-09 14:35:51 UTC (rev 4076)
+++ branches/7.7.x/client/src/main/java/org/teiid/client/security/ILogon.java 2012-05-09 14:36:12 UTC (rev 4077)
@@ -37,9 +37,11 @@
static final String KRB5TOKEN = "KRB5TOKEN"; //$NON-NLS-1$
static final String KRB5_ESTABLISHED = "KRB5_CONTEXT_ESTABLISHED"; //$NON-NLS-1$
+ @Secure
LogonResult logon(Properties connectionProperties)
throws LogonException, TeiidComponentException, CommunicationException;
+ @Secure
LogonResult neogitiateGssLogin(Properties connectionProperties, byte[] serviceToken, boolean createSession) throws LogonException;
/**
@@ -60,5 +62,6 @@
*/
ResultsFuture<?> logoff() throws InvalidSessionException, TeiidComponentException;
+ @Secure
void assertIdentity(SessionToken sessionId) throws InvalidSessionException, TeiidComponentException, CommunicationException;
}
Added: branches/7.7.x/client/src/main/java/org/teiid/client/security/Secure.java
===================================================================
--- branches/7.7.x/client/src/main/java/org/teiid/client/security/Secure.java (rev 0)
+++ branches/7.7.x/client/src/main/java/org/teiid/client/security/Secure.java 2012-05-09 14:36:12 UTC (rev 4077)
@@ -0,0 +1,40 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.client.security;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+(a)Target({ElementType.METHOD})
+(a)Retention(RetentionPolicy.RUNTIME)
+@Inherited
+@Documented
+public @interface Secure {
+
+ boolean optional() default false;
+
+}
Property changes on: branches/7.7.x/client/src/main/java/org/teiid/client/security/Secure.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Modified: branches/7.7.x/client/src/main/java/org/teiid/jdbc/ConnectionImpl.java
===================================================================
--- branches/7.7.x/client/src/main/java/org/teiid/jdbc/ConnectionImpl.java 2012-05-09 14:35:51 UTC (rev 4076)
+++ branches/7.7.x/client/src/main/java/org/teiid/jdbc/ConnectionImpl.java 2012-05-09 14:36:12 UTC (rev 4077)
@@ -99,7 +99,8 @@
private String debugLog;
// the last query annotations
private Collection<Annotation> annotations;
- private Properties connectionProps;
+ private Properties connectionProps;
+ private Properties payload;
public ConnectionImpl(ServerConnection serverConn, Properties info, String url) {
this.connectionProps = info;
@@ -828,6 +829,7 @@
}
public void recycleConnection() {
+ this.payload = null;
try {
//close all open statements
this.closeStatements();
@@ -1005,6 +1007,14 @@
setPassword(oldPassword);
}
}
+ }
+
+ public Properties getPayload() {
+ return payload;
+ }
+
+ public void setPayload(Properties payload) {
+ this.payload = payload;
}
}
Modified: branches/7.7.x/client/src/main/java/org/teiid/jdbc/JDBCURL.java
===================================================================
--- branches/7.7.x/client/src/main/java/org/teiid/jdbc/JDBCURL.java 2012-05-09 14:35:51 UTC (rev 4076)
+++ branches/7.7.x/client/src/main/java/org/teiid/jdbc/JDBCURL.java 2012-05-09 14:36:12 UTC (rev 4077)
@@ -75,7 +75,8 @@
TeiidURL.CONNECTION.DISCOVERY_STRATEGY,
TeiidURL.CONNECTION.PASSTHROUGH_AUTHENTICATION,
TeiidURL.CONNECTION.JAAS_NAME,
- TeiidURL.CONNECTION.KERBEROS_SERVICE_PRINCIPLE_NAME));
+ TeiidURL.CONNECTION.KERBEROS_SERVICE_PRINCIPLE_NAME,
+ TeiidURL.CONNECTION.ENCRYPT_REQUESTS));
props.addAll(EXECUTION_PROPERTIES);
return Collections.unmodifiableSet(props);
}
Modified: branches/7.7.x/client/src/main/java/org/teiid/jdbc/StatementImpl.java
===================================================================
--- branches/7.7.x/client/src/main/java/org/teiid/jdbc/StatementImpl.java 2012-05-09 14:35:51 UTC (rev 4076)
+++ branches/7.7.x/client/src/main/java/org/teiid/jdbc/StatementImpl.java 2012-05-09 14:36:12 UTC (rev 4077)
@@ -155,8 +155,8 @@
protected Map outParamIndexMap = new HashMap();
private static Pattern TRANSACTION_STATEMENT = Pattern.compile("\\s*(commit|rollback|(start\\s+transaction))\\s*;?", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
- private static Pattern SET_STATEMENT = Pattern.compile("\\s*set\\s+((?:session authorization)|(?:\\w+))\\s+(?:([a-zA-Z](?:\\w|_)*)|((?:'[^']*')+));?", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
- private static Pattern SHOW_STATEMENT = Pattern.compile("\\s*show\\s+(\\w*);?", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
+ private static Pattern SET_STATEMENT = Pattern.compile("\\s*set(?:\\s+(payload))?\\s+((?:session authorization)|(?:[a-zA-Z]\\w*))\\s+(?:([a-zA-Z]\\w*)|((?:'[^']*')+));?", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
+ private static Pattern SHOW_STATEMENT = Pattern.compile("\\s*show\\s+([a-zA-Z]\\w*);?", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
/**
* Factory Constructor
* @param driverConnection
@@ -407,14 +407,22 @@
if (resultsMode == ResultsMode.RESULTSET) {
throw new TeiidSQLException(JDBCPlugin.Util.getString("StatementImpl.set_result_set")); //$NON-NLS-1$
}
- String key = match.group(1);
- String value = match.group(2);
+ String key = match.group(2);
+ String value = match.group(3);
if (value == null) {
- value = match.group(3);
+ value = match.group(4);
value = StringUtil.replaceAll(value, "''", "'"); //$NON-NLS-1$ //$NON-NLS-2$
value = value.substring(1, value.length() - 1);
}
- if ("SESSION AUTHORIZATION".equalsIgnoreCase(key)) { //$NON-NLS-1$
+ if (match.group(1) != null) {
+ //payload case
+ Properties p = this.getMMConnection().getPayload();
+ if (p == null) {
+ p = new Properties();
+ this.getMMConnection().setPayload(p);
+ }
+ p.setProperty(key, value);
+ } else if ("SESSION AUTHORIZATION".equalsIgnoreCase(key)) { //$NON-NLS-1$
this.getMMConnection().changeUser(value, this.getMMConnection().getPassword());
} else if (key.equalsIgnoreCase(TeiidURL.CONNECTION.PASSWORD)) {
this.getMMConnection().setPassword(value);
@@ -565,7 +573,11 @@
this.getConnection().beginLocalTxnIfNeeded();
this.currentRequestID = this.driverConnection.nextRequestID();
// Create a request message
- reqMsg.setExecutionPayload(this.payload);
+ if (this.payload != null) {
+ reqMsg.setExecutionPayload(this.payload);
+ } else {
+ reqMsg.setExecutionPayload(this.getMMConnection().getPayload());
+ }
reqMsg.setCursorType(this.resultSetType);
reqMsg.setFetchSize(this.fetchSize);
reqMsg.setRowLimit(this.maxRows);
Modified: branches/7.7.x/client/src/main/java/org/teiid/jdbc/TeiidDataSource.java
===================================================================
--- branches/7.7.x/client/src/main/java/org/teiid/jdbc/TeiidDataSource.java 2012-05-09 14:35:51 UTC (rev 4076)
+++ branches/7.7.x/client/src/main/java/org/teiid/jdbc/TeiidDataSource.java 2012-05-09 14:36:12 UTC (rev 4077)
@@ -107,6 +107,10 @@
* Name of Kerberos KDC service principle name
*/
private String kerberosServicePrincipleName;
+ /**
+ * If not using ssl determines whether requests with the associated command payload should be encrypted
+ */
+ private boolean encryptRequests;
public TeiidDataSource() {
}
@@ -517,5 +521,17 @@
public void setKerberosServicePrincipleName(String kerberosServerName) {
this.kerberosServicePrincipleName = kerberosServerName;
}
+
+ public void setEncryptRequests(boolean encryptRequests) {
+ this.encryptRequests = encryptRequests;
+ }
+
+ public boolean isEncryptRequests() {
+ return encryptRequests;
+ }
+
+ public boolean getEncryptRequests() {
+ return encryptRequests;
+ }
}
Modified: branches/7.7.x/client/src/main/java/org/teiid/net/TeiidURL.java
===================================================================
--- branches/7.7.x/client/src/main/java/org/teiid/net/TeiidURL.java 2012-05-09 14:35:51 UTC (rev 4076)
+++ branches/7.7.x/client/src/main/java/org/teiid/net/TeiidURL.java 2012-05-09 14:36:12 UTC (rev 4077)
@@ -86,6 +86,8 @@
public static final String JAAS_NAME = "jaasName"; //$NON-NLS-1$
public static final String KERBEROS_SERVICE_PRINCIPLE_NAME = "kerberosServicePrincipleName"; //$NON-NLS-1$;
+
+ public static final String ENCRYPT_REQUESTS = "encryptRequests"; //$NON-NLS-1$;
}
public static final String DOT_DELIMITER = "."; //$NON-NLS-1$
Modified: branches/7.7.x/client/src/main/java/org/teiid/net/socket/SocketServerConnection.java
===================================================================
--- branches/7.7.x/client/src/main/java/org/teiid/net/socket/SocketServerConnection.java 2012-05-09 14:35:51 UTC (rev 4076)
+++ branches/7.7.x/client/src/main/java/org/teiid/net/socket/SocketServerConnection.java 2012-05-09 14:36:12 UTC (rev 4077)
@@ -49,6 +49,7 @@
import org.teiid.client.util.ResultsFuture;
import org.teiid.core.TeiidComponentException;
import org.teiid.core.TeiidException;
+import org.teiid.core.util.PropertiesUtils;
import org.teiid.gss.MakeGSS;
import org.teiid.jdbc.JDBCPlugin;
import org.teiid.net.CommunicationException;
@@ -211,7 +212,7 @@
}
public <T> T getService(Class<T> iface) {
- return iface.cast(Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class[] {iface}, new SocketServerInstanceImpl.RemoteInvocationHandler(iface) {
+ return iface.cast(Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class[] {iface}, new SocketServerInstanceImpl.RemoteInvocationHandler(iface, PropertiesUtils.getBooleanProperty(connProps, TeiidURL.CONNECTION.ENCRYPT_REQUESTS, false)) {
@Override
protected SocketServerInstance getInstance() throws CommunicationException {
if (failOver && System.currentTimeMillis() - lastPing > pingFailOverInterval) {
Modified: branches/7.7.x/client/src/main/java/org/teiid/net/socket/SocketServerInstanceImpl.java
===================================================================
--- branches/7.7.x/client/src/main/java/org/teiid/net/socket/SocketServerInstanceImpl.java 2012-05-09 14:35:51 UTC (rev 4076)
+++ branches/7.7.x/client/src/main/java/org/teiid/net/socket/SocketServerInstanceImpl.java 2012-05-09 14:36:12 UTC (rev 4077)
@@ -31,6 +31,7 @@
import java.lang.reflect.Proxy;
import java.net.InetSocketAddress;
import java.net.SocketTimeoutException;
+import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
@@ -43,7 +44,7 @@
import java.util.logging.Level;
import java.util.logging.Logger;
-import org.teiid.client.security.ILogon;
+import org.teiid.client.security.Secure;
import org.teiid.client.util.ExceptionHolder;
import org.teiid.client.util.ExceptionUtil;
import org.teiid.client.util.ResultsFuture;
@@ -77,6 +78,7 @@
private Cryptor cryptor;
private String serverVersion;
private AuthenticationType authType = AuthenticationType.CLEARTEXT;
+ private HashMap<Class<?>, Object> serviceMap = new HashMap<Class<?>, Object>();
private boolean hasReader;
@@ -275,15 +277,19 @@
}
}
- @SuppressWarnings("unchecked")
@Override
- public <T> T getService(Class<T> iface) {
- return (T)Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class[] {iface}, new RemoteInvocationHandler(iface) {
- @Override
- protected SocketServerInstanceImpl getInstance() {
- return SocketServerInstanceImpl.this;
- }
- });
+ public synchronized <T> T getService(Class<T> iface) {
+ Object service = this.serviceMap.get(iface);
+ if (service == null) {
+ service = Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class[] {iface}, new RemoteInvocationHandler(iface, false) {
+ @Override
+ protected SocketServerInstanceImpl getInstance() {
+ return SocketServerInstanceImpl.this;
+ }
+ });
+ this.serviceMap.put(iface, service);
+ }
+ return iface.cast(service);
}
public long getSynchTimeout() {
@@ -292,12 +298,12 @@
public static abstract class RemoteInvocationHandler implements InvocationHandler {
- private boolean secure;
private Class<?> targetClass;
+ private boolean secureOptional;
- public RemoteInvocationHandler(Class<?> targetClass) {
+ public RemoteInvocationHandler(Class<?> targetClass, boolean secureOptional) {
this.targetClass = targetClass;
- this.secure = ILogon.class.isAssignableFrom(targetClass);
+ this.secureOptional = secureOptional;
}
@Override
@@ -309,7 +315,8 @@
Message message = new Message();
message.setContents(new ServiceInvocationStruct(args, method.getName(),
targetClass));
- if (secure) {
+ Secure secure = method.getAnnotation(Secure.class);
+ if (secure != null && (!secure.optional() || secureOptional)) {
message.setContents(instance.getCryptor().sealObject(message.getContents()));
}
ResultsFuture<Object> results = new ResultsFuture<Object>() {
Modified: branches/7.7.x/client/src/test/java/org/teiid/jdbc/TestStatement.java
===================================================================
--- branches/7.7.x/client/src/test/java/org/teiid/jdbc/TestStatement.java 2012-05-09 14:35:51 UTC (rev 4076)
+++ branches/7.7.x/client/src/test/java/org/teiid/jdbc/TestStatement.java 2012-05-09 14:36:12 UTC (rev 4077)
@@ -71,6 +71,14 @@
assertEquals("b'ar", p.get("foo")); //$NON-NLS-1$ //$NON-NLS-2$
}
+ @Test public void testSetPayloadStatement() throws Exception {
+ ConnectionImpl conn = Mockito.mock(ConnectionImpl.class);
+ Properties p = new Properties();
+ Mockito.stub(conn.getExecutionProperties()).toReturn(p);
+ StatementImpl statement = new StatementImpl(conn, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
+ assertFalse(statement.execute("set payload foo bar")); //$NON-NLS-1$
+ }
+
@Test public void testSetAuthorizationStatement() throws Exception {
ConnectionImpl conn = Mockito.mock(ConnectionImpl.class);
Properties p = new Properties();
Modified: branches/7.7.x/client/src/test/java/org/teiid/jdbc/TestTeiidDriver.java
===================================================================
--- branches/7.7.x/client/src/test/java/org/teiid/jdbc/TestTeiidDriver.java 2012-05-09 14:35:51 UTC (rev 4076)
+++ branches/7.7.x/client/src/test/java/org/teiid/jdbc/TestTeiidDriver.java 2012-05-09 14:36:12 UTC (rev 4077)
@@ -138,7 +138,7 @@
@Test public void testGetPropertyInfo1() throws Exception {
DriverPropertyInfo info[] = drv.getPropertyInfo("jdbc:teiid:vdb@mm://localhost:12345;applicationName=x", null); //$NON-NLS-1$
- assertEquals(23, info.length);
+ assertEquals(24, info.length);
assertEquals(false, info[0].required);
assertEquals("ApplicationName", info[0].name); //$NON-NLS-1$
assertEquals("x", info[0].value); //$NON-NLS-1$
Modified: branches/7.7.x/documentation/client-developers-guide/src/main/docbook/en-US/content/jdbc-connection.xml
===================================================================
--- branches/7.7.x/documentation/client-developers-guide/src/main/docbook/en-US/content/jdbc-connection.xml 2012-05-09 14:35:51 UTC (rev 4076)
+++ branches/7.7.x/documentation/client-developers-guide/src/main/docbook/en-US/content/jdbc-connection.xml 2012-05-09 14:36:12 UTC (rev 4077)
@@ -280,7 +280,17 @@
See the Admin Guide for configuration required for GSS</para>
</entry>
</row>
-
+ <row>
+ <entry>
+ <code>encryptRequests</code>
+ </entry>
+ <entry>
+ <code>boolean</code>
+ </entry>
+ <entry>
+ <para>Only applies to non-SSL socket connections. When "true" the request message and any associate payload will be encrypted using the connection cryptor. Default false.</para>
+ </entry>
+ </row>
</tbody>
</tgroup>
</table>
Modified: branches/7.7.x/documentation/client-developers-guide/src/main/docbook/en-US/content/jdbc-extensions.xml
===================================================================
--- branches/7.7.x/documentation/client-developers-guide/src/main/docbook/en-US/content/jdbc-extensions.xml 2012-05-09 14:35:51 UTC (rev 4076)
+++ branches/7.7.x/documentation/client-developers-guide/src/main/docbook/en-US/content/jdbc-extensions.xml 2012-05-09 14:36:12 UTC (rev 4077)
@@ -193,7 +193,7 @@
<para>SET Syntax:
</para>
<listitem>
- <para>SET (parameter|SESSION AUTHORIZATION) value
+ <para>SET [PAYLOAD] (parameter|SESSION AUTHORIZATION) value
</para>
</listitem>
</itemizedlist>
@@ -206,6 +206,9 @@
<listitem>
<para>The value may be either a non-quoted identifier or a quoted string literal value.</para>
</listitem>
+ <listitem>
+ <para>If payload is specified, e.g. "SET PAYLOAD x y", then a session scoped payload properties object will have the corresponding name value pair set. The payload object is not fully session scoped. It will be removed from the session when the XAConnection handle is closed / returned to the pool (assumes the use of TeiidDataSource). The session scoped payload is superseded by the usage of TeiidStatement.setPayload.</para>
+ </listitem>
</itemizedlist>
<para>The SET statement is most commonly used to control planning and execution.</para>
<itemizedlist>
11 years, 10 months
teiid SVN: r4076 - in branches/7.7.x/connectors/connector-infinispan/src/main: java/org/teiid/resource/adapter/infinispan and 1 other directories.
by teiid-commits@lists.jboss.org
Author: van.halbert
Date: 2012-05-09 10:35:51 -0400 (Wed, 09 May 2012)
New Revision: 4076
Modified:
branches/7.7.x/connectors/connector-infinispan/src/main/ear/infinispan-ds.xml
branches/7.7.x/connectors/connector-infinispan/src/main/java/org/teiid/resource/adapter/infinispan/InfinispanConnectionImpl.java
branches/7.7.x/connectors/connector-infinispan/src/main/java/org/teiid/resource/adapter/infinispan/InfinispanManagedConnectionFactory.java
branches/7.7.x/connectors/connector-infinispan/src/main/rar/META-INF/ra.xml
Log:
Teiid-1992 fixed the passing of the data source property: remoteServerList and how its handled for creating the cache manager
Modified: branches/7.7.x/connectors/connector-infinispan/src/main/ear/infinispan-ds.xml
===================================================================
--- branches/7.7.x/connectors/connector-infinispan/src/main/ear/infinispan-ds.xml 2012-05-08 17:12:27 UTC (rev 4075)
+++ branches/7.7.x/connectors/connector-infinispan/src/main/ear/infinispan-ds.xml 2012-05-09 14:35:51 UTC (rev 4076)
@@ -10,10 +10,11 @@
<rar-name>infinispan-jca.ear#connector-infinispan.rar</rar-name>
<!-- connection interface; (do not change this) -->
<connection-definition>javax.resource.cci.ConnectionFactory</connection-definition>
-
- <!-- (OPTIONAL) Infinispan Server List -->
- <!-- config-property name="RemoteInfinispanServerList">host:port[;host:port...]</config-property-->
-<min-pool-size>5</min-pool-size>
+
+ <!-- Infinispan server list - host:port[;host:port...] (required)-->
+ <config-property name="RemoteServerList">localhost:11222</config-property>
+
+ <min-pool-size>0</min-pool-size>
<max-pool-size>20</max-pool-size>
</no-tx-connection-factory>
Modified: branches/7.7.x/connectors/connector-infinispan/src/main/java/org/teiid/resource/adapter/infinispan/InfinispanConnectionImpl.java
===================================================================
--- branches/7.7.x/connectors/connector-infinispan/src/main/java/org/teiid/resource/adapter/infinispan/InfinispanConnectionImpl.java 2012-05-08 17:12:27 UTC (rev 4075)
+++ branches/7.7.x/connectors/connector-infinispan/src/main/java/org/teiid/resource/adapter/infinispan/InfinispanConnectionImpl.java 2012-05-09 14:35:51 UTC (rev 4076)
@@ -1,5 +1,5 @@
/*
- * JBoss, Home of Professional Open Source.
+sele * JBoss, Home of Professional Open Source.
* See the COPYRIGHT.txt file distributed with this work for information
* regarding copyright ownership. Some portions may be licensed
* to Red Hat, Inc. under one or more contributor license agreements.
Modified: branches/7.7.x/connectors/connector-infinispan/src/main/java/org/teiid/resource/adapter/infinispan/InfinispanManagedConnectionFactory.java
===================================================================
--- branches/7.7.x/connectors/connector-infinispan/src/main/java/org/teiid/resource/adapter/infinispan/InfinispanManagedConnectionFactory.java 2012-05-08 17:12:27 UTC (rev 4075)
+++ branches/7.7.x/connectors/connector-infinispan/src/main/java/org/teiid/resource/adapter/infinispan/InfinispanManagedConnectionFactory.java 2012-05-09 14:35:51 UTC (rev 4076)
@@ -31,26 +31,30 @@
private String remoteServerList;
private RemoteCacheManager cacheContainer;
- private Object lock = new Object();
+
@Override
public BasicConnectionFactory createConnectionFactory() throws ResourceException {
- synchronized(lock) {
-
- this.cacheContainer = getOrCreateCacheContainer();
- if (this.cacheContainer == null) {
- throw new ResourceException("Unable to create Infinispan CacheContainer" );
- }
- }
return new BasicConnectionFactory() {
private static final long serialVersionUID = 1L;
+
+ private Object lock = new Object();
+
@Override
public InfinispanConnectionImpl getConnection() throws ResourceException {
+ synchronized(lock) {
+
+ RemoteCacheManager cc = getOrCreateCacheContainer();
+ if (cc == null) {
+ throw new ResourceException("Unable to create Infinispan CacheContainer" );
+ }
+
+ }
return new InfinispanConnectionImpl(InfinispanManagedConnectionFactory.this);
}
};
@@ -66,12 +70,12 @@
* must be in the appropriate format of <code>host:port[;host:port...]</code> that would be used when defining an Infinispan
* {@link RemoteCacheManager} instance. If the value is missing, <code>localhost:11311</code> is assumed.
*
- * @param remoteInfinispanServerList the server list in appropriate <code>server:port;server2:port2</code> format.
+ * @param remoteServerList the server list in appropriate <code>server:port;server2:port2</code> format.
*/
- public synchronized void setRemoteInfinispanServerList( String remoteInfinispanServerList ) {
- if (this.remoteServerList == remoteInfinispanServerList || this.remoteServerList != null
- && this.remoteServerList.equals(remoteInfinispanServerList)) return; // unchanged
- this.remoteServerList = remoteInfinispanServerList;
+ public synchronized void setRemoteServerList( String remoteServerList ) {
+ if (this.remoteServerList == remoteServerList || this.remoteServerList != null
+ && this.remoteServerList.equals(remoteServerList)) return; // unchanged
+ this.remoteServerList = remoteServerList;
}
@@ -83,9 +87,12 @@
return this.cacheContainer;
}
if (getRemoteServerList() == null || getRemoteServerList().equals("")) {
- return new RemoteCacheManager();
+ this.cacheContainer = new RemoteCacheManager();
+ return this.cacheContainer;
}
- return new RemoteCacheManager(getRemoteServerList());
+ this.cacheContainer = new RemoteCacheManager(getRemoteServerList());
+
+ return this.cacheContainer;
}
Modified: branches/7.7.x/connectors/connector-infinispan/src/main/rar/META-INF/ra.xml
===================================================================
--- branches/7.7.x/connectors/connector-infinispan/src/main/rar/META-INF/ra.xml 2012-05-08 17:12:27 UTC (rev 4075)
+++ branches/7.7.x/connectors/connector-infinispan/src/main/rar/META-INF/ra.xml 2012-05-09 14:35:51 UTC (rev 4076)
@@ -35,18 +35,17 @@
<outbound-resourceadapter>
<connection-definition>
<managedconnectionfactory-class>org.teiid.resource.adapter.infinispan.InfinispanManagedConnectionFactory</managedconnectionfactory-class>
+
+ <config-property>
+ <description>{$display:"Infinispan Server List",$description:"Infinispan Server List",$required:"true"}</description>
+ <config-property-name>RemoteServerList</config-property-name>
+ <config-property-type>java.lang.String</config-property-type>
+ </config-property>
<connectionfactory-interface>javax.resource.cci.ConnectionFactory</connectionfactory-interface>
<connectionfactory-impl-class>org.teiid.resource.adapter.custom.spi.WrappedConnectionFactory</connectionfactory-impl-class>
<connection-interface>javax.resource.cci.Connection</connection-interface>
- <connection-impl-class>org.teiid.resource.adapter.custom.spi.WrappedConnection</connection-impl-class>
-
- <!-- config-property>
- <description>{$display:"Infinispan Server List",$description:"Infinispan Server List (host:port[;host:port...])",$required:"true"}</description>
- <config-property-name>RemoteServerList</config-property-name>
- <config-property-type>java.lang.String</config-property-type>
- <config-property-value>localhost:11311</config-property-value>
- </config-property-->
+ <connection-impl-class>org.teiid.resource.adapter.custom.spi.WrappedConnection</connection-impl-class>
</connection-definition>
11 years, 10 months
teiid SVN: r4075 - in branches/7.7.x: engine/src/main/java/org/teiid/dqp/internal/datamgr and 1 other directories.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2012-05-08 13:12:27 -0400 (Tue, 08 May 2012)
New Revision: 4075
Modified:
branches/7.7.x/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/JDBCBaseExecution.java
branches/7.7.x/engine/src/main/java/org/teiid/dqp/internal/datamgr/ConnectorWorkItem.java
branches/7.7.x/metadata/src/main/java/org/teiid/metadata/index/RecordFactory.java
Log:
TEIID-2020: Running Sybase procedure with jconnect driver in Teiid fails
Modified: branches/7.7.x/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/JDBCBaseExecution.java
===================================================================
--- branches/7.7.x/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/JDBCBaseExecution.java 2012-05-08 13:55:30 UTC (rev 4074)
+++ branches/7.7.x/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/JDBCBaseExecution.java 2012-05-08 17:12:27 UTC (rev 4075)
@@ -38,6 +38,7 @@
import org.teiid.translator.Execution;
import org.teiid.translator.ExecutionContext;
import org.teiid.translator.TranslatorException;
+import org.teiid.translator.jdbc.sybase.SybaseExecutionFactory;
/**
@@ -135,7 +136,10 @@
}
protected void setSizeContraints(Statement statement) {
- try {
+ try {
+ if (statement instanceof CallableStatement && this.executionFactory instanceof SybaseExecutionFactory) {
+ return;
+ }
statement.setFetchSize(fetchSize);
} catch (SQLException e) {
if (LogManager.isMessageToBeRecorded(LogConstants.CTX_CONNECTOR, MessageLevel.DETAIL)) {
Modified: branches/7.7.x/engine/src/main/java/org/teiid/dqp/internal/datamgr/ConnectorWorkItem.java
===================================================================
--- branches/7.7.x/engine/src/main/java/org/teiid/dqp/internal/datamgr/ConnectorWorkItem.java 2012-05-08 13:55:30 UTC (rev 4074)
+++ branches/7.7.x/engine/src/main/java/org/teiid/dqp/internal/datamgr/ConnectorWorkItem.java 2012-05-08 17:12:27 UTC (rev 4075)
@@ -218,6 +218,9 @@
// Translate the command
Command command = this.requestMsg.getCommand();
this.expectedColumns = command.getProjectedSymbols().size();
+ if (command instanceof StoredProcedure) {
+ this.expectedColumns = ((StoredProcedure)command).getResultSetColumns().size();
+ }
LanguageBridgeFactory factory = new LanguageBridgeFactory(queryMetadata);
factory.setConvertIn(!this.connector.supportsInCriteria());
this.translatedCommand = factory.translate(command);
Modified: branches/7.7.x/metadata/src/main/java/org/teiid/metadata/index/RecordFactory.java
===================================================================
--- branches/7.7.x/metadata/src/main/java/org/teiid/metadata/index/RecordFactory.java 2012-05-08 13:55:30 UTC (rev 4074)
+++ branches/7.7.x/metadata/src/main/java/org/teiid/metadata/index/RecordFactory.java 2012-05-08 17:12:27 UTC (rev 4075)
@@ -800,6 +800,8 @@
case MetadataConstants.PARAMETER_TYPES.RETURN_VALUE:
type = ProcedureParameter.Type.ReturnValue;
break;
+ default:
+ throw new IllegalArgumentException("Invalid parameter type, please ensure all parameter types are valid in Designer.");
}
paramRd.setType(type);
11 years, 10 months
teiid SVN: r4074 - branches/7.7.x/console/src/main/resources/META-INF.
by teiid-commits@lists.jboss.org
Author: tejones
Date: 2012-05-08 09:55:30 -0400 (Tue, 08 May 2012)
New Revision: 4074
Modified:
branches/7.7.x/console/src/main/resources/META-INF/rhq-plugin.xml
Log:
TEIID-1996: Corrected session id parameter description for getPlan
Modified: branches/7.7.x/console/src/main/resources/META-INF/rhq-plugin.xml
===================================================================
--- branches/7.7.x/console/src/main/resources/META-INF/rhq-plugin.xml 2012-05-07 20:10:17 UTC (rev 4073)
+++ branches/7.7.x/console/src/main/resources/META-INF/rhq-plugin.xml 2012-05-08 13:55:30 UTC (rev 4074)
@@ -209,7 +209,7 @@
<parameters>
<c:simple-property displayName="Session ID" name="sessionID"
type="string" required="true"
- description="The ID of the session that the request to cancel is associated with" />
+ description="The ID of the session that the targeted request is associated with" />
<c:simple-property displayName="Request ID" name="requestID"
type="long" required="true" description="The ID of the request to retrieve the query plan for" />
</parameters>
11 years, 10 months
teiid SVN: r4073 - in trunk: admin/src/test/java/org/teiid/adminapi/impl and 4 other directories.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2012-05-07 16:10:17 -0400 (Mon, 07 May 2012)
New Revision: 4073
Added:
trunk/admin/src/test/resources/model-not-unique-vdb.xml
Modified:
trunk/admin/src/main/java/org/teiid/adminapi/impl/ModelMetaData.java
trunk/admin/src/main/java/org/teiid/adminapi/impl/VDBMetaData.java
trunk/admin/src/main/java/org/teiid/adminapi/impl/VDBMetadataParser.java
trunk/admin/src/test/java/org/teiid/adminapi/impl/TestVDBMetadataParser.java
trunk/admin/src/test/resources/parser-test-vdb.xml
trunk/client/src/main/resources/vdb-deployer.xsd
trunk/jboss-integration/src/main/java/org/teiid/jboss/IntegrationPlugin.java
trunk/jboss-integration/src/main/java/org/teiid/jboss/VDBParserDeployer.java
trunk/jboss-integration/src/main/java/org/teiid/jboss/VDBService.java
trunk/jboss-integration/src/main/resources/org/teiid/jboss/i18n.properties
Log:
TEIID-2024 adding various validations
Modified: trunk/admin/src/main/java/org/teiid/adminapi/impl/ModelMetaData.java
===================================================================
--- trunk/admin/src/main/java/org/teiid/adminapi/impl/ModelMetaData.java 2012-05-07 19:02:20 UTC (rev 4072)
+++ trunk/admin/src/main/java/org/teiid/adminapi/impl/ModelMetaData.java 2012-05-07 20:10:17 UTC (rev 4073)
@@ -144,6 +144,7 @@
}
public void setSourceMappings(List<SourceMappingMetadata> sources){
+ this.sources.getMap().clear();
for (SourceMappingMetadata source: sources) {
addSourceMapping(source.getName(), source.getTranslatorName(), source.getConnectionJndiName());
}
@@ -172,12 +173,12 @@
return s.getTranslatorName();
}
- public void addSourceMapping(String name, String translatorName, String connJndiName) {
- this.sources.getMap().put(name, new SourceMappingMetadata(name, translatorName, connJndiName));
+ public SourceMappingMetadata addSourceMapping(String name, String translatorName, String connJndiName) {
+ return this.sources.getMap().put(name, new SourceMappingMetadata(name, translatorName, connJndiName));
}
public void addSourceMapping(SourceMappingMetadata source) {
- this.sources.getMap().put(source.getName(), new SourceMappingMetadata(source.getName(), source.getTranslatorName(), source.getConnectionJndiName()));
+ this.addSourceMapping(source.getName(), source.getTranslatorName(), source.getConnectionJndiName());
}
public List<ValidationError> getErrors(){
Modified: trunk/admin/src/main/java/org/teiid/adminapi/impl/VDBMetaData.java
===================================================================
--- trunk/admin/src/main/java/org/teiid/adminapi/impl/VDBMetaData.java 2012-05-07 19:02:20 UTC (rev 4072)
+++ trunk/admin/src/main/java/org/teiid/adminapi/impl/VDBMetaData.java 2012-05-07 20:10:17 UTC (rev 4073)
@@ -22,7 +22,11 @@
package org.teiid.adminapi.impl;
import java.net.URL;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
import org.teiid.adminapi.DataPolicy;
import org.teiid.adminapi.Model;
@@ -179,14 +183,15 @@
* @param models
*/
public void setModels(List<Model> models) {
+ this.models.getMap().clear();
for (Model obj : models) {
ModelMetaData model = (ModelMetaData) obj;
addModel(model);
}
}
- public void addModel(ModelMetaData m) {
- this.models.getMap().put(m.getName(), m);
+ public ModelMetaData addModel(ModelMetaData m) {
+ return this.models.getMap().put(m.getName(), m);
}
@Override
Modified: trunk/admin/src/main/java/org/teiid/adminapi/impl/VDBMetadataParser.java
===================================================================
--- trunk/admin/src/main/java/org/teiid/adminapi/impl/VDBMetadataParser.java 2012-05-07 19:02:20 UTC (rev 4072)
+++ trunk/admin/src/main/java/org/teiid/adminapi/impl/VDBMetadataParser.java 2012-05-07 20:10:17 UTC (rev 4073)
@@ -30,12 +30,17 @@
import java.util.Map;
import java.util.Properties;
+import javax.xml.XMLConstants;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;
+import javax.xml.transform.stax.StAXSource;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+import javax.xml.validation.Validator;
import org.teiid.adminapi.AdminPlugin;
import org.teiid.adminapi.DataPolicy;
@@ -43,6 +48,7 @@
import org.teiid.adminapi.impl.DataPolicyMetadata.PermissionMetaData;
import org.teiid.adminapi.impl.ModelMetaData.ValidationError;
import org.teiid.core.types.XMLType;
+import org.xml.sax.SAXException;
@SuppressWarnings("nls")
public class VDBMetadataParser {
@@ -50,25 +56,47 @@
public static VDBMetaData unmarshell(InputStream content) throws XMLStreamException {
XMLInputFactory inputFactory=XMLType.getXmlInputFactory();
XMLStreamReader reader = inputFactory.createXMLStreamReader(content);
-
- // elements
- while (reader.hasNext() && (reader.nextTag() != XMLStreamConstants.END_ELEMENT)) {
- Element element = Element.forName(reader.getLocalName());
- switch (element) {
- case VDB:
- VDBMetaData vdb = new VDBMetaData();
- Properties props = getAttributes(reader);
- vdb.setName(props.getProperty(Element.NAME.getLocalName()));
- vdb.setVersion(Integer.parseInt(props.getProperty(Element.VERSION.getLocalName())));
- parseVDB(reader, vdb);
- return vdb;
- default:
- throw new XMLStreamException(AdminPlugin.Util.gs("unexpected_element1",reader.getName(), Element.VDB.getLocalName()), reader.getLocation());
- }
- }
+ try {
+ // elements
+ while (reader.hasNext() && (reader.nextTag() != XMLStreamConstants.END_ELEMENT)) {
+ Element element = Element.forName(reader.getLocalName());
+ switch (element) {
+ case VDB:
+ VDBMetaData vdb = new VDBMetaData();
+ Properties props = getAttributes(reader);
+ vdb.setName(props.getProperty(Element.NAME.getLocalName()));
+ vdb.setVersion(Integer.parseInt(props.getProperty(Element.VERSION.getLocalName())));
+ parseVDB(reader, vdb);
+ return vdb;
+ default:
+ throw new XMLStreamException(AdminPlugin.Util.gs("unexpected_element1",reader.getName(), Element.VDB.getLocalName()), reader.getLocation());
+ }
+ }
+ } finally {
+ try {
+ content.close();
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
return null;
}
+ public static void validate(InputStream content) throws SAXException,
+ IOException, XMLStreamException {
+ try {
+ XMLInputFactory inputFactory = XMLType.getXmlInputFactory();
+ XMLStreamReader reader = inputFactory.createXMLStreamReader(content);
+ SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
+ Schema schema = schemaFactory.newSchema(VDBMetaData.class.getResource("/vdb-deployer.xsd")); //$NON-NLS-1$
+ Validator v = schema.newValidator();
+ v.validate(new StAXSource(reader));
+ } finally {
+ content.close();
+ }
+ }
+
private static void parseVDB(XMLStreamReader reader, VDBMetaData vdb) throws XMLStreamException {
while (reader.hasNext() && (reader.nextTag() != XMLStreamConstants.END_ELEMENT)) {
Element element = Element.forName(reader.getLocalName());
Modified: trunk/admin/src/test/java/org/teiid/adminapi/impl/TestVDBMetadataParser.java
===================================================================
--- trunk/admin/src/test/java/org/teiid/adminapi/impl/TestVDBMetadataParser.java 2012-05-07 19:02:20 UTC (rev 4072)
+++ trunk/admin/src/test/java/org/teiid/adminapi/impl/TestVDBMetadataParser.java 2012-05-07 20:10:17 UTC (rev 4073)
@@ -1,3 +1,24 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
package org.teiid.adminapi.impl;
import java.io.FileInputStream;
@@ -4,14 +25,23 @@
import org.junit.Test;
import org.teiid.core.util.UnitTestUtil;
+import org.xml.sax.SAXException;
@SuppressWarnings("nls")
public class TestVDBMetadataParser {
@Test
- public void testparseVDB() throws Exception {
+ public void testParseVDB() throws Exception {
FileInputStream in = new FileInputStream(UnitTestUtil.getTestDataPath() + "/parser-test-vdb.xml");
+ VDBMetadataParser.validate(in);
+ in = new FileInputStream(UnitTestUtil.getTestDataPath() + "/parser-test-vdb.xml");
VDBMetaData vdb = VDBMetadataParser.unmarshell(in);
TestVDBMetaData.validateVDB(vdb);
}
+
+ @Test(expected=SAXException.class) public void testModelNameUniqueness() throws Exception {
+ FileInputStream in = new FileInputStream(UnitTestUtil.getTestDataPath() + "/model-not-unique-vdb.xml");
+ VDBMetadataParser.validate(in);
+ }
+
}
Added: trunk/admin/src/test/resources/model-not-unique-vdb.xml
===================================================================
--- trunk/admin/src/test/resources/model-not-unique-vdb.xml (rev 0)
+++ trunk/admin/src/test/resources/model-not-unique-vdb.xml 2012-05-07 20:10:17 UTC (rev 4073)
@@ -0,0 +1,39 @@
+<vdb name="myVDB" version="1">
+ <description>vdb description</description>
+ <property name="vdb-property2" value="vdb-value2"></property>
+ <property name="vdb-property" value="vdb-value"></property>
+ <model name="model-one" type="PHYSICAL" visible="false">
+ <description>model description</description>
+ <property name="model-prop" value="model-value-override"></property>
+ <source name="s1" translator-name="translator" connection-jndi-name="java:mybinding"></source>
+ <validation-error severity="ERROR">There is an error in VDB</validation-error>
+ </model>
+ <model name="model-one" type="VIRTUAL" visible="true">
+ <property name="model-prop" value="model-value"></property>
+ <source name="s1" translator-name="translator" connection-jndi-name="java:binding-one"></source>
+ <source name="s2" translator-name="translator" connection-jndi-name="java:binding-two"></source>
+ <metadata type="DDL"><![CDATA[DDL Here]]></metadata>
+ </model>
+ <translator name="oracleOverride" type="oracle" description="hello world">
+ <property name="my-property" value="my-value"></property>
+ </translator>
+ <data-role name="roleOne" any-authenticated="false" allow-create-temporary-tables="true">
+ <description>roleOne described</description>
+ <permission>
+ <resource-name>myTable.T1</resource-name>
+ <allow-read>true</allow-read>
+ </permission>
+ <permission>
+ <resource-name>myTable.T2</resource-name>
+ <allow-create>true</allow-create>
+ <allow-read>false</allow-read>
+ <allow-update>true</allow-update>
+ <allow-delete>true</allow-delete>
+ <allow-execute>true</allow-execute>
+ <allow-alter>true</allow-alter>
+ </permission>
+ <mapped-role-name>ROLE1</mapped-role-name>
+ <mapped-role-name>ROLE2</mapped-role-name>
+ </data-role>
+</vdb>
+
Property changes on: trunk/admin/src/test/resources/model-not-unique-vdb.xml
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Modified: trunk/admin/src/test/resources/parser-test-vdb.xml
===================================================================
--- trunk/admin/src/test/resources/parser-test-vdb.xml 2012-05-07 19:02:20 UTC (rev 4072)
+++ trunk/admin/src/test/resources/parser-test-vdb.xml 2012-05-07 20:10:17 UTC (rev 4073)
@@ -25,12 +25,12 @@
</permission>
<permission>
<resource-name>myTable.T2</resource-name>
+ <allow-create>true</allow-create>
<allow-read>false</allow-read>
+ <allow-update>true</allow-update>
<allow-delete>true</allow-delete>
+ <allow-execute>true</allow-execute>
<allow-alter>true</allow-alter>
- <allow-create>true</allow-create>
- <allow-update>true</allow-update>
- <allow-execute>true</allow-execute>
</permission>
<mapped-role-name>ROLE1</mapped-role-name>
<mapped-role-name>ROLE2</mapped-role-name>
Modified: trunk/client/src/main/resources/vdb-deployer.xsd
===================================================================
--- trunk/client/src/main/resources/vdb-deployer.xsd 2012-05-07 19:02:20 UTC (rev 4072)
+++ trunk/client/src/main/resources/vdb-deployer.xsd 2012-05-07 20:10:17 UTC (rev 4073)
@@ -40,8 +40,12 @@
</xs:documentation>
</xs:annotation>
<xs:complexType>
- <xs:attribute name="type" type="xs:string" default="DDL"/>
- </xs:complexType>
+ <xs:simpleContent>
+ <xs:extension base="xs:string">
+ <xs:attribute name="type" type="xs:string" default="DDL"/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
</xs:element>
<xs:element name="validation-error" minOccurs="0" maxOccurs="unbounded">
<xs:annotation>
@@ -70,6 +74,10 @@
<xs:attribute name="visible" type="xs:boolean" default="true"/>
<xs:attribute name="path" type="xs:string"/>
</xs:complexType>
+ <xs:unique name="sourceNameUnique">
+ <xs:selector xpath="source"/>
+ <xs:field xpath="@name"/>
+ </xs:unique>
</xs:element>
<xs:element name="translator" maxOccurs="unbounded" minOccurs="0">
<xs:annotation>
@@ -133,6 +141,10 @@
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="version" type="xs:int" use="required"/>
</xs:complexType>
+ <xs:unique name="modelNameUnique">
+ <xs:selector xpath="model"/>
+ <xs:field xpath="@name"/>
+ </xs:unique>
</xs:element>
<xs:complexType name="property">
<xs:annotation>
Modified: trunk/jboss-integration/src/main/java/org/teiid/jboss/IntegrationPlugin.java
===================================================================
--- trunk/jboss-integration/src/main/java/org/teiid/jboss/IntegrationPlugin.java 2012-05-07 19:02:20 UTC (rev 4072)
+++ trunk/jboss-integration/src/main/java/org/teiid/jboss/IntegrationPlugin.java 2012-05-07 20:10:17 UTC (rev 4073)
@@ -66,6 +66,7 @@
TEIID50026, // VDB undeployed
TEIID50029, // dynamic metadata loaded
TEIID50030,
+ TEIID50031, // multiple sources, non-multisource
TEIID50032, // duplicate VDB
TEIID50033, // duplicate source name in vdb
TEIID50034, // Source name mismatch
Modified: trunk/jboss-integration/src/main/java/org/teiid/jboss/VDBParserDeployer.java
===================================================================
--- trunk/jboss-integration/src/main/java/org/teiid/jboss/VDBParserDeployer.java 2012-05-07 19:02:20 UTC (rev 4072)
+++ trunk/jboss-integration/src/main/java/org/teiid/jboss/VDBParserDeployer.java 2012-05-07 20:10:17 UTC (rev 4073)
@@ -43,6 +43,7 @@
import org.teiid.logging.LogManager;
import org.teiid.metadata.VdbConstants;
import org.teiid.metadata.index.IndexMetadataStore;
+import org.xml.sax.SAXException;
/**
@@ -107,6 +108,7 @@
private VDBMetaData parseVDBXML(VirtualFile file, DeploymentUnit deploymentUnit, DeploymentPhaseContext phaseContext) throws DeploymentUnitProcessingException {
try {
+ VDBMetadataParser.validate(file.openStream());
VDBMetaData vdb = VDBMetadataParser.unmarshell(file.openStream());
ServiceController<?> sc = phaseContext.getServiceRegistry().getService(TeiidServiceNames.OBJECT_SERIALIZER);
ObjectSerializer serializer = ObjectSerializer.class.cast(sc.getValue());
@@ -120,6 +122,8 @@
throw new DeploymentUnitProcessingException(IntegrationPlugin.Event.TEIID50017.name(), e);
} catch (IOException e) {
throw new DeploymentUnitProcessingException(IntegrationPlugin.Event.TEIID50017.name(), e);
+ } catch (SAXException e) {
+ throw new DeploymentUnitProcessingException(IntegrationPlugin.Event.TEIID50017.name(), e);
}
}
Modified: trunk/jboss-integration/src/main/java/org/teiid/jboss/VDBService.java
===================================================================
--- trunk/jboss-integration/src/main/java/org/teiid/jboss/VDBService.java 2012-05-07 19:02:20 UTC (rev 4072)
+++ trunk/jboss-integration/src/main/java/org/teiid/jboss/VDBService.java 2012-05-07 20:10:17 UTC (rev 4073)
@@ -219,6 +219,9 @@
if (sourceNames.size() != new HashSet<String>(sourceNames).size()) {
throw new StartException(IntegrationPlugin.Util.gs(IntegrationPlugin.Event.TEIID50033, model.getName(), deployment.getName(), deployment.getVersion()));
}
+ if (sourceNames.size() > 1 && !model.isSupportsMultiSourceBindings()) {
+ throw new StartException(IntegrationPlugin.Util.gs(IntegrationPlugin.Event.TEIID50031, model.getName(), deployment.getName(), deployment.getVersion()));
+ }
for (String source:sourceNames) {
ConnectorManager cm = cmr.getConnectorManager(source);
String name = model.getSourceTranslatorName(source);
Modified: trunk/jboss-integration/src/main/resources/org/teiid/jboss/i18n.properties
===================================================================
--- trunk/jboss-integration/src/main/resources/org/teiid/jboss/i18n.properties 2012-05-07 19:02:20 UTC (rev 4072)
+++ trunk/jboss-integration/src/main/resources/org/teiid/jboss/i18n.properties 2012-05-07 20:10:17 UTC (rev 4073)
@@ -67,6 +67,7 @@
TEIID50036=VDB {0}.{1} model "{2}" metadata failed to load. Reason:{3}
TEIID50042=error setting state {0}
TEIID50033=Source names are not unique for model {0} in {1}.{2}
+TEIID50031=Multiple sources on non multi-source model {0} in {1}.{2}
TEIID50034=There are different sources with the name {0} in {1}.{2}
TEIID50043=Invalid metadata file found at {0}; delete this file and restart server.
TEIID50069=Failed to load module {0}
11 years, 10 months
teiid SVN: r4072 - trunk/connectors/translator-jpa.
by teiid-commits@lists.jboss.org
Author: rareddy
Date: 2012-05-07 15:02:20 -0400 (Mon, 07 May 2012)
New Revision: 4072
Modified:
trunk/connectors/translator-jpa/
Log:
TEIID-2011: Adding ignores
Property changes on: trunk/connectors/translator-jpa
___________________________________________________________________
Added: svn:ignore
+ .project
.settings
.classpath
11 years, 10 months
teiid SVN: r4070 - trunk/build/kits/jboss-as7/modules/org/jboss/teiid/translator/jpa/main.
by teiid-commits@lists.jboss.org
Author: rareddy
Date: 2012-05-07 14:50:39 -0400 (Mon, 07 May 2012)
New Revision: 4070
Added:
trunk/build/kits/jboss-as7/modules/org/jboss/teiid/translator/jpa/main/module.xml
Log:
TEIID-2011: Adding initial code for supporting the JPA based translator
Added: trunk/build/kits/jboss-as7/modules/org/jboss/teiid/translator/jpa/main/module.xml
===================================================================
--- trunk/build/kits/jboss-as7/modules/org/jboss/teiid/translator/jpa/main/module.xml (rev 0)
+++ trunk/build/kits/jboss-as7/modules/org/jboss/teiid/translator/jpa/main/module.xml 2012-05-07 18:50:39 UTC (rev 4070)
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module xmlns="urn:jboss:module:1.0" name="org.jboss.teiid.translator.jpa">
+ <resources>
+ <resource-root path="translator-jpa-${project.version}.jar" />
+ <!-- Insert resources here -->
+ </resources>
+
+ <dependencies>
+ <module name="javax.api"/>
+ <module name="javax.resource.api"/>
+ <module name="org.jboss.teiid.common-core" />
+ <module name="org.jboss.teiid.api" />
+ <module name="javax.persistence.api"/>
+ <module name="org.hibernate"/>
+ <module name="org.jboss.teiid.translator.jdbc"/>
+ </dependencies>
+</module>
Property changes on: trunk/build/kits/jboss-as7/modules/org/jboss/teiid/translator/jpa/main/module.xml
___________________________________________________________________
Added: svn:mime-type
+ text/plain
11 years, 10 months
teiid SVN: r4069 - in trunk: build/assembly/jboss-as7 and 29 other directories.
by teiid-commits@lists.jboss.org
Author: rareddy
Date: 2012-05-07 14:40:54 -0400 (Mon, 07 May 2012)
New Revision: 4069
Added:
trunk/build/kits/jboss-as7/modules/org/jboss/teiid/translator/jpa/
trunk/build/kits/jboss-as7/modules/org/jboss/teiid/translator/jpa/main/
trunk/connectors/translator-jpa/
trunk/connectors/translator-jpa/pom.xml
trunk/connectors/translator-jpa/src/
trunk/connectors/translator-jpa/src/main/
trunk/connectors/translator-jpa/src/main/java/
trunk/connectors/translator-jpa/src/main/java/org/
trunk/connectors/translator-jpa/src/main/java/org/teiid/
trunk/connectors/translator-jpa/src/main/java/org/teiid/translator/
trunk/connectors/translator-jpa/src/main/java/org/teiid/translator/jpa/
trunk/connectors/translator-jpa/src/main/java/org/teiid/translator/jpa/JPA2ExecutionFactory.java
trunk/connectors/translator-jpa/src/main/java/org/teiid/translator/jpa/JPAMetadataProcessor.java
trunk/connectors/translator-jpa/src/main/java/org/teiid/translator/jpa/JPAPlugin.java
trunk/connectors/translator-jpa/src/main/java/org/teiid/translator/jpa/JPQLBaseExecution.java
trunk/connectors/translator-jpa/src/main/java/org/teiid/translator/jpa/JPQLQueryExecution.java
trunk/connectors/translator-jpa/src/main/java/org/teiid/translator/jpa/JPQLSelectVisitor.java
trunk/connectors/translator-jpa/src/main/java/org/teiid/translator/jpa/JPQLUpdateExecution.java
trunk/connectors/translator-jpa/src/main/java/org/teiid/translator/jpa/JPQLUpdateQueryVisitor.java
trunk/connectors/translator-jpa/src/main/resources/
trunk/connectors/translator-jpa/src/main/resources/META-INF/
trunk/connectors/translator-jpa/src/main/resources/META-INF/MANIFEST.MF
trunk/connectors/translator-jpa/src/main/resources/META-INF/services/
trunk/connectors/translator-jpa/src/main/resources/META-INF/services/org.teiid.translator.ExecutionFactory
trunk/connectors/translator-jpa/src/main/resources/org/
trunk/connectors/translator-jpa/src/main/resources/org/teiid/
trunk/connectors/translator-jpa/src/main/resources/org/teiid/translator/
trunk/connectors/translator-jpa/src/main/resources/org/teiid/translator/jpa/
trunk/connectors/translator-jpa/src/main/resources/org/teiid/translator/jpa/i18n.properties
trunk/connectors/translator-jpa/src/test/
trunk/connectors/translator-jpa/src/test/java/
trunk/connectors/translator-jpa/src/test/java/org/
trunk/connectors/translator-jpa/src/test/java/org/teiid/
trunk/connectors/translator-jpa/src/test/java/org/teiid/translator/
trunk/connectors/translator-jpa/src/test/java/org/teiid/translator/jpa/
trunk/connectors/translator-jpa/src/test/java/org/teiid/translator/jpa/TestJSelectJPQLVisitor.java
trunk/connectors/translator-jpa/src/test/resources/
trunk/connectors/translator-jpa/src/test/resources/sakila.ddl
trunk/connectors/translator-jpa/target/
trunk/connectors/translator-jpa/target/classes/
trunk/connectors/translator-jpa/target/classes/META-INF/
trunk/connectors/translator-jpa/target/classes/META-INF/MANIFEST.MF
Modified:
trunk/api/src/main/java/org/teiid/metadata/ColumnSet.java
trunk/api/src/main/java/org/teiid/metadata/Table.java
trunk/build/assembly/jboss-as7/dist.xml
trunk/build/kits/jboss-as7/standalone/configuration/standalone-teiid.xml
trunk/connectors/pom.xml
Log:
TEIID-2011: Adding initial code for supporting the JPA based translator
Modified: trunk/api/src/main/java/org/teiid/metadata/ColumnSet.java
===================================================================
--- trunk/api/src/main/java/org/teiid/metadata/ColumnSet.java 2012-05-07 18:28:19 UTC (rev 4068)
+++ trunk/api/src/main/java/org/teiid/metadata/ColumnSet.java 2012-05-07 18:40:54 UTC (rev 4069)
@@ -56,4 +56,12 @@
this.parent = parent;
}
+ public Column getColumn(String name) {
+ for (Column c:columns) {
+ if (c.getCanonicalName().equals(name.toUpperCase())) {
+ return c;
+ }
+ }
+ return null;
+ }
}
\ No newline at end of file
Modified: trunk/api/src/main/java/org/teiid/metadata/Table.java
===================================================================
--- trunk/api/src/main/java/org/teiid/metadata/Table.java 2012-05-07 18:28:19 UTC (rev 4068)
+++ trunk/api/src/main/java/org/teiid/metadata/Table.java 2012-05-07 18:40:54 UTC (rev 4069)
@@ -209,6 +209,15 @@
this.foriegnKeys = foriegnKeys;
}
+ public ForeignKey getForeignKey(String name) {
+ for (ForeignKey fk:this.foriegnKeys) {
+ if (fk.getName().equals(name)) {
+ return fk;
+ }
+ }
+ return null;
+ }
+
public List<KeyRecord> getIndexes() {
return this.indexes;
}
Modified: trunk/build/assembly/jboss-as7/dist.xml
===================================================================
--- trunk/build/assembly/jboss-as7/dist.xml 2012-05-07 18:28:19 UTC (rev 4068)
+++ trunk/build/assembly/jboss-as7/dist.xml 2012-05-07 18:40:54 UTC (rev 4069)
@@ -388,6 +388,28 @@
<outputDirectory>modules/org/jboss/teiid/translator/hive/main</outputDirectory>
<fileMode>0644</fileMode>
</binaries>
+ </moduleSet>
+
+ <moduleSet>
+ <includeSubModules>true</includeSubModules>
+ <useAllReactorProjects>true</useAllReactorProjects>
+ <includes>
+ <include>org.jboss.teiid.connectors:translator-jpa</include>
+ </includes>
+ <binaries>
+ <includeDependencies>true</includeDependencies>
+ <unpack>false</unpack>
+ <dependencySets>
+ <dependencySet>
+ <useProjectArtifact>true</useProjectArtifact>
+ <unpack>false</unpack>
+ <useTransitiveDependencies>false</useTransitiveDependencies>
+ <useDefaultExcludes>true</useDefaultExcludes>
+ </dependencySet>
+ </dependencySets>
+ <outputDirectory>modules/org/jboss/teiid/translator/jpa/main</outputDirectory>
+ <fileMode>0644</fileMode>
+ </binaries>
</moduleSet>
<!-- Include the JOPR plugin
Modified: trunk/build/kits/jboss-as7/standalone/configuration/standalone-teiid.xml
===================================================================
--- trunk/build/kits/jboss-as7/standalone/configuration/standalone-teiid.xml 2012-05-07 18:28:19 UTC (rev 4068)
+++ trunk/build/kits/jboss-as7/standalone/configuration/standalone-teiid.xml 2012-05-07 18:40:54 UTC (rev 4069)
@@ -308,6 +308,7 @@
<translator name="ws" module="org.jboss.teiid.translator.ws"/>
<translator name="salesforce" module="org.jboss.teiid.translator.salesforce"/>
<translator name="hive" module="org.jboss.teiid.translator.hive"/>
+ <translator name="jpa2" module="org.jboss.teiid.translator.jpa"/>
</subsystem>
<subsystem xmlns="urn:jboss:domain:threads:1.1">
Modified: trunk/connectors/pom.xml
===================================================================
--- trunk/connectors/pom.xml 2012-05-07 18:28:19 UTC (rev 4068)
+++ trunk/connectors/pom.xml 2012-05-07 18:40:54 UTC (rev 4069)
@@ -105,5 +105,6 @@
<module>translator-ws</module>
<module>translator-olap</module>
<module>translator-hive</module>
+ <module>translator-jpa</module>
</modules>
</project>
Added: trunk/connectors/translator-jpa/pom.xml
===================================================================
--- trunk/connectors/translator-jpa/pom.xml (rev 0)
+++ trunk/connectors/translator-jpa/pom.xml 2012-05-07 18:40:54 UTC (rev 4069)
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <parent>
+ <artifactId>connectors</artifactId>
+ <groupId>org.jboss.teiid</groupId>
+ <version>8.1.0.Alpha1-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>translator-jpa</artifactId>
+ <groupId>org.jboss.teiid.connectors</groupId>
+ <name>JPA2 Translator</name>
+ <description>This translator provides access to any JPA based entities</description>
+ <properties>
+ <version.org.hibernate.javax.persistence.hibernate-jpa-2.0-api>1.0.1.Final</version.org.hibernate.javax.persistence.hibernate-jpa-2.0-api>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.jboss.teiid</groupId>
+ <artifactId>teiid-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.teiid</groupId>
+ <artifactId>teiid-common-core</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.teiid.connectors</groupId>
+ <artifactId>translator-jdbc</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.teiid.connectors</groupId>
+ <artifactId>translator-jdbc</artifactId>
+ <version>${project.version}</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.resource</groupId>
+ <artifactId>connector-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.hibernate.javax.persistence</groupId>
+ <artifactId>hibernate-jpa-2.0-api</artifactId>
+ <version>${version.org.hibernate.javax.persistence.hibernate-jpa-2.0-api}</version>
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <configuration>
+ <archive>
+ <manifestFile>src/main/resources/META-INF/MANIFEST.MF</manifestFile>
+ </archive>
+ </configuration>
+ </plugin>
+ </plugins>
+
+ <outputDirectory>target/classes</outputDirectory>
+ <resources>
+ <resource>
+ <directory>src/main/resources</directory>
+ <filtering>true</filtering>
+ <includes>
+ <include>**/*.xml</include>
+ <include>**/*.properties</include>
+ </includes>
+ </resource>
+ <resource>
+ <directory>src/main/resources</directory>
+ <filtering>false</filtering>
+ <excludes>
+ <exclude>**/*.xml</exclude>
+ <exclude>**/*.properties</exclude>
+ </excludes>
+ </resource>
+ </resources>
+ </build>
+</project>
Added: trunk/connectors/translator-jpa/src/main/java/org/teiid/translator/jpa/JPA2ExecutionFactory.java
===================================================================
--- trunk/connectors/translator-jpa/src/main/java/org/teiid/translator/jpa/JPA2ExecutionFactory.java (rev 0)
+++ trunk/connectors/translator-jpa/src/main/java/org/teiid/translator/jpa/JPA2ExecutionFactory.java 2012-05-07 18:40:54 UTC (rev 4069)
@@ -0,0 +1,278 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+package org.teiid.translator.jpa;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+
+import org.teiid.core.util.PropertiesUtils;
+import org.teiid.language.Call;
+import org.teiid.language.Command;
+import org.teiid.language.QueryExpression;
+import org.teiid.metadata.MetadataFactory;
+import org.teiid.metadata.RuntimeMetadata;
+import org.teiid.translator.ExecutionContext;
+import org.teiid.translator.ExecutionFactory;
+import org.teiid.translator.ProcedureExecution;
+import org.teiid.translator.ResultSetExecution;
+import org.teiid.translator.SourceSystemFunctions;
+import org.teiid.translator.Translator;
+import org.teiid.translator.TranslatorException;
+import org.teiid.translator.UpdateExecution;
+import org.teiid.translator.jdbc.AliasModifier;
+import org.teiid.translator.jdbc.FunctionModifier;
+
+@Translator(name="jpa2", description="A translator for JPA2 based entities")
+public class JPA2ExecutionFactory extends ExecutionFactory<EntityManagerFactory, EntityManager> {
+ private Map<String, FunctionModifier> functionModifiers = new TreeMap<String, FunctionModifier>(String.CASE_INSENSITIVE_ORDER);
+
+ @Override
+ public void start() throws TranslatorException {
+ super.start();
+ setSupportsInnerJoins(true);
+ setSupportsOrderBy(true);
+ setSupportsSelectDistinct(true);
+ setSupportedJoinCriteria(SupportedJoinCriteria.KEY);
+ setSupportsOuterJoins(true);
+
+ registerFunctionModifier(SourceSystemFunctions.LCASE, new AliasModifier("lower")); //$NON-NLS-1$
+ registerFunctionModifier(SourceSystemFunctions.UCASE, new AliasModifier("upper")); //$NON-NLS-1$
+ registerFunctionModifier(SourceSystemFunctions.CURDATE, new AliasModifier("current_date")); //$NON-NLS-1$
+ registerFunctionModifier(SourceSystemFunctions.CURTIME, new AliasModifier("current_time")); //$NON-NLS-1$
+ }
+
+ @Override
+ public EntityManager getConnection(EntityManagerFactory factory, ExecutionContext executionContext) throws TranslatorException {
+ if (factory == null) {
+ return null;
+ }
+ return factory.createEntityManager();
+ }
+
+ @Override
+ public void closeConnection(EntityManager connection, EntityManagerFactory factory) {
+ connection.close();
+ }
+
+ @Override
+ public ResultSetExecution createResultSetExecution(QueryExpression command, ExecutionContext executionContext, RuntimeMetadata metadata, EntityManager connection) throws TranslatorException {
+ return new JPQLQueryExecution(this, command, executionContext, metadata, connection);
+ }
+
+ @Override
+ public ProcedureExecution createProcedureExecution(Call command, ExecutionContext executionContext, RuntimeMetadata metadata, EntityManager connection) throws TranslatorException {
+ return super.createProcedureExecution(command, executionContext, metadata, connection);
+ }
+
+ @Override
+ public UpdateExecution createUpdateExecution(Command command, ExecutionContext executionContext, RuntimeMetadata metadata, EntityManager connection) throws TranslatorException {
+ return new JPQLUpdateExecution(command, executionContext, metadata, connection);
+ }
+
+ @Override
+ public void getMetadata(MetadataFactory mf, EntityManager em) throws TranslatorException {
+ JPAMetadataProcessor metadataProcessor = new JPAMetadataProcessor();
+ PropertiesUtils.setBeanProperties(metadataProcessor, mf.getImportProperties(), "importer"); //$NON-NLS-1$
+ metadataProcessor.getMetadata(mf, em);
+ }
+
+
+ @Override
+ public boolean supportsSelectExpression() {
+ return true;
+ }
+
+ @Override
+ public boolean supportsAliasedTable() {
+ return true;
+ }
+
+ @Override
+ public boolean supportsInlineViews() {
+ return true;
+ }
+
+ @Override
+ public boolean supportsCompareCriteriaEquals() {
+ return true;
+ }
+
+ @Override
+ public boolean supportsCompareCriteriaOrdered() {
+ return true;
+ }
+
+ @Override
+ public boolean supportsLikeCriteria() {
+ return true;
+ }
+
+ @Override
+ public boolean supportsInCriteria() {
+ return true;
+ }
+
+ @Override
+ public boolean supportsInCriteriaSubquery() {
+ return false;
+ }
+
+ @Override
+ public boolean supportsIsNullCriteria() {
+ return true;
+ }
+
+ @Override
+ public boolean supportsOrCriteria() {
+ return true;
+ }
+
+ @Override
+ public boolean supportsNotCriteria() {
+ return true;
+ }
+
+ @Override
+ public boolean supportsExistsCriteria() {
+ return true;
+ }
+
+ @Override
+ public boolean supportsGroupBy() {
+ return true;
+ }
+
+ @Override
+ public boolean supportsHaving() {
+ return true;
+ }
+
+ @Override
+ public boolean supportsAggregatesSum() {
+ return true;
+ }
+
+ @Override
+ public boolean supportsAggregatesAvg() {
+ return true;
+ }
+
+ @Override
+ public boolean supportsAggregatesMin() {
+ return true;
+ }
+
+ @Override
+ public boolean supportsAggregatesMax() {
+ return true;
+ }
+
+ @Override
+ public boolean supportsAggregatesCount() {
+ return true;
+ }
+
+ @Override
+ public boolean supportsAggregatesCountStar() {
+ return true;
+ }
+
+ @Override
+ public boolean supportsAggregatesDistinct() {
+ return true;
+ }
+
+ @Override
+ public boolean supportsScalarSubqueries() {
+ return true;
+ }
+
+ @Override
+ public boolean useAnsiJoin() {
+ return true;
+ }
+
+ @Override
+ public boolean supportsDependentJoins() {
+ return true;
+ }
+
+ @Override
+ public boolean supportsSelfJoins() {
+ return true;
+ }
+
+ @Override
+ public List<String> getSupportedFunctions() {
+ List<String> supportedFunctions = new ArrayList<String>();
+ supportedFunctions.addAll(getDefaultSupportedFunctions());
+
+ // String functions
+ supportedFunctions.add(SourceSystemFunctions.CONCAT);
+ supportedFunctions.add(SourceSystemFunctions.SUBSTRING);
+ supportedFunctions.add(SourceSystemFunctions.TRIM);
+ supportedFunctions.add(SourceSystemFunctions.LCASE);
+ supportedFunctions.add(SourceSystemFunctions.UCASE);
+ supportedFunctions.add(SourceSystemFunctions.LENGTH);
+ supportedFunctions.add(SourceSystemFunctions.LOCATE);
+
+ // airthamatic functions
+ supportedFunctions.add(SourceSystemFunctions.ABS);
+ supportedFunctions.add(SourceSystemFunctions.SQRT);
+ supportedFunctions.add(SourceSystemFunctions.MOD);
+ supportedFunctions.add(SourceSystemFunctions.CURDATE);
+ supportedFunctions.add(SourceSystemFunctions.CURTIME);
+
+ supportedFunctions.add(SourceSystemFunctions.COALESCE);
+ supportedFunctions.add(SourceSystemFunctions.NULLIF);
+
+ return supportedFunctions;
+ }
+
+ /**
+ * Return a map of function name to FunctionModifier.
+ * @return Map of function name to FunctionModifier.
+ */
+ public Map<String, FunctionModifier> getFunctionModifiers() {
+ return functionModifiers;
+ }
+
+ /**
+ * Add the {@link FunctionModifier} to the set of known modifiers.
+ * @param name
+ * @param modifier
+ */
+ public void registerFunctionModifier(String name, FunctionModifier modifier) {
+ this.functionModifiers.put(name, modifier);
+ }
+
+
+ public List<String> getDefaultSupportedFunctions(){
+ return Arrays.asList(new String[] { "+", "-", "*", "/" }); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ }
+}
Added: trunk/connectors/translator-jpa/src/main/java/org/teiid/translator/jpa/JPAMetadataProcessor.java
===================================================================
--- trunk/connectors/translator-jpa/src/main/java/org/teiid/translator/jpa/JPAMetadataProcessor.java (rev 0)
+++ trunk/connectors/translator-jpa/src/main/java/org/teiid/translator/jpa/JPAMetadataProcessor.java 2012-05-07 18:40:54 UTC (rev 4069)
@@ -0,0 +1,323 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+package org.teiid.translator.jpa;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.persistence.EntityManager;
+import javax.persistence.metamodel.Attribute;
+import javax.persistence.metamodel.EmbeddableType;
+import javax.persistence.metamodel.EntityType;
+import javax.persistence.metamodel.ManagedType;
+import javax.persistence.metamodel.Metamodel;
+import javax.persistence.metamodel.PluralAttribute;
+import javax.persistence.metamodel.SingularAttribute;
+import javax.persistence.metamodel.Type.PersistenceType;
+
+import org.teiid.core.types.BlobType;
+import org.teiid.core.types.ClobType;
+import org.teiid.language.SQLConstants.Tokens;
+import org.teiid.metadata.Column;
+import org.teiid.metadata.ForeignKey;
+import org.teiid.metadata.KeyRecord;
+import org.teiid.metadata.MetadataFactory;
+import org.teiid.metadata.Table;
+import org.teiid.translator.TranslatorException;
+import org.teiid.translator.TypeFacility;
+
+/**
+ * TODO:
+ * - support of abstract entities is an issue, should we represent base and extended types, just extended types?
+ *
+ */
+@SuppressWarnings("nls")
+public class JPAMetadataProcessor {
+ public static final String KEY_ASSOSIATED_WITH_FOREIGN_TABLE = "assosiated_with_table";
+ public static final String ENTITYCLASS= "entity_class";
+
+ final static Map<Class<?>, Class<?>> map = new HashMap<Class<?>, Class<?>>();
+ static {
+ map.put(boolean.class, Boolean.class);
+ map.put(byte.class, Byte.class);
+ map.put(short.class, Short.class);
+ map.put(char.class, Character.class);
+ map.put(int.class, Integer.class);
+ map.put(long.class, Long.class);
+ map.put(float.class, Float.class);
+ map.put(double.class, Double.class);
+ map.put(byte[].class, BlobType.class);
+ map.put(char[].class, ClobType.class);
+ map.put(Byte[].class, BlobType.class);
+ map.put(Character[].class, ClobType.class);
+
+ map.put(Boolean.class, Boolean.class);
+ map.put(Byte.class, Byte.class);
+ map.put(Short.class, Short.class);
+ map.put(Character.class, Character.class);
+ map.put(Integer.class, Integer.class);
+ map.put(Long.class, Long.class);
+ map.put(Float.class, Float.class);
+ map.put(Double.class, Double.class);
+ map.put(Calendar.class, java.sql.Timestamp.class);
+ }
+
+ public void getMetadata(MetadataFactory mf, EntityManager entityManager) throws TranslatorException {
+ Metamodel model = entityManager.getMetamodel();
+
+ Set<EntityType<?>> entities = model.getEntities();
+ for (EntityType<?> entity:entities) {
+ addEntity(mf, model, entity);
+ }
+
+ // take a second swipe and add Foreign Keys
+ for (EntityType<?> entity:entities) {
+ Table t = mf.getTable(entity.getName());
+ addForeignKeys(mf, model, entity, t);
+ }
+ }
+
+ private Table addEntity(MetadataFactory mf, Metamodel model, EntityType<?> entity) throws TranslatorException {
+ Table table = mf.getTable(entity.getName());
+ if (table == null) {
+ table = mf.addTable(entity.getName());
+ table.setSupportsUpdate(true);
+ table.setProperty(ENTITYCLASS, entity.getJavaType().getCanonicalName());
+ addPrimaryKey(mf, model, entity, table);
+ addSingularAttributes(mf, model, entity, table);
+ }
+ return table;
+ }
+
+ private boolean columnExists(String name, Table table) {
+ if (table.getColumns() == null) {
+ return false;
+ }
+ for (Column existingColumn: table.getColumns()) {
+ if (existingColumn.getName().equals(name)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private Column addColumn(MetadataFactory mf, String name, String type, Table entityTable) throws TranslatorException {
+ if (!columnExists(name, entityTable)) {
+ Column c = mf.addColumn(name, type, entityTable);
+ c.setUpdatable(true);
+ return c;
+ }
+ return entityTable.getColumn(name);
+ }
+
+ private void addForiegnKey(MetadataFactory mf, String name, List<String> columnNames, String referenceTable, Table table) throws TranslatorException {
+ ForeignKey fk = mf.addForiegnKey("FK_"+name, columnNames, referenceTable, table);
+ for (String column:columnNames) {
+ Column c = table.getColumn(column);
+ c.setProperty(KEY_ASSOSIATED_WITH_FOREIGN_TABLE, mf.getName()+Tokens.DOT+referenceTable);
+ }
+ fk.setNameInSource(name);
+ }
+
+ private void addSingularAttributes(MetadataFactory mf, Metamodel model, ManagedType<?> entity, Table entityTable) throws TranslatorException {
+ for (Attribute<?, ?> attr:entity.getAttributes()) {
+ if (!attr.isCollection()) {
+ boolean simpleType = isSimpleType(attr.getJavaType());
+ if (simpleType) {
+ Column column = addColumn(mf, attr.getName(), TypeFacility.getDataTypeName(getJavaDataType(attr.getJavaType())), entityTable);
+ if (((SingularAttribute)attr).isOptional()) {
+ column.setDefaultValue(null);
+ }
+ }
+ else {
+ boolean classFound = false;
+ // If this attribute is a @Embeddable then add its columns as
+ // this tables columns
+ for (EmbeddableType<?> embeddable:model.getEmbeddables()) {
+ if (embeddable.getJavaType().equals(attr.getJavaType())) {
+ addSingularAttributes(mf, model, embeddable, entityTable);
+ classFound = true;
+ break;
+ }
+ }
+
+ if (!classFound) {
+ // if the attribute is @Entity then add entity's PK as column on this
+ // table, then add that column as FK
+ for (EntityType et:model.getEntities()) {
+ if (et.getJavaType().equals(attr.getJavaType())) {
+ Table attributeTable = addEntity(mf, model, et);
+ KeyRecord pk = attributeTable.getPrimaryKey();
+ if (pk != null) { // TODO: entities must have PK, so this check is not needed.
+ ArrayList<String> keys = new ArrayList<String>();
+ for (Column column:pk.getColumns()) {
+ addColumn(mf, column.getName(), column.getDatatype().getRuntimeTypeName(), entityTable);
+ keys.add(column.getName());
+ }
+ if (!foreignKeyExists(keys, entityTable)) {
+ addForiegnKey(mf, attr.getName(), keys, attributeTable.getName(), entityTable);
+ }
+ }
+ else {
+ throw new TranslatorException(JPAPlugin.Util.gs(JPAPlugin.Event.TEIID14001, attributeTable.getName()));
+ }
+ classFound = true;
+ break;
+ }
+ }
+ }
+
+ if (!classFound) {
+ throw new TranslatorException(JPAPlugin.Util.gs(JPAPlugin.Event.TEIID14002, attr.getName()));
+ }
+ }
+ }
+ }
+ }
+
+ private boolean isSimpleType(Class type) {
+ return type.isPrimitive() || type.equals(String.class)
+ || type.equals(BigDecimal.class) || type.equals(Date.class)
+ || type.equals(BigInteger.class)
+ || map.containsKey(type);
+ }
+
+ private void addForeignKeys(MetadataFactory mf, Metamodel model, ManagedType<?> entity, Table entityTable) throws TranslatorException {
+ for (Attribute<?, ?> attr:entity.getAttributes()) {
+ if (attr.isCollection()) {
+
+ PluralAttribute pa = (PluralAttribute)attr;
+ Table forignTable = null;
+
+ for (EntityType et:model.getEntities()) {
+ if (et.getJavaType().equals(pa.getElementType().getJavaType())) {
+ forignTable = mf.getTable(et.getName());
+ break;
+ }
+ }
+
+ if (forignTable == null) {
+ continue;
+ }
+
+ // add foreign keys as columns in table first; check if they exist first
+ ArrayList<String> keys = new ArrayList<String>();
+ KeyRecord pk = entityTable.getPrimaryKey();
+ for (Column entityColumn:pk.getColumns()) {
+ addColumn(mf, entityColumn.getName(), entityColumn.getDatatype().getRuntimeTypeName(), forignTable);
+ keys.add(entityColumn.getName());
+ }
+
+ if (!foreignKeyExists(keys, forignTable)) {
+ addForiegnKey(mf, attr.getName(), keys, entityTable.getName(), forignTable);
+ }
+ }
+ }
+ }
+
+ private boolean foreignKeyExists(List<String> keys, Table forignTable) {
+ boolean fkExists = false;
+ for (ForeignKey fk:forignTable.getForeignKeys()) {
+ boolean allKeysFound = true;
+ for (String key:keys) {
+ boolean keyfound = false;
+ for (Column col:fk.getColumns()) {
+ if (col.getName().equals(key)) {
+ keyfound = true;
+ break;
+ }
+ }
+ if (!keyfound) {
+ allKeysFound = false;
+ break;
+ }
+ }
+
+ if (allKeysFound) {
+ fkExists = true;
+ break;
+ }
+ }
+ return fkExists;
+ }
+
+ private void addPrimaryKey(MetadataFactory mf, Metamodel model, EntityType<?> entity, Table entityTable) throws TranslatorException {
+ // figure out the PK
+ if (entity.hasSingleIdAttribute()) {
+ if (entity.getIdType().getPersistenceType().equals(PersistenceType.BASIC)) {
+ SingularAttribute<?, ?> pkattr = entity.getId(entity.getIdType().getJavaType());
+ addColumn(mf, pkattr.getName(), TypeFacility.getDataTypeName(getJavaDataType(pkattr.getJavaType())), entityTable);
+ mf.addPrimaryKey("PK_"+entity.getName(), Arrays.asList(pkattr.getName()), entityTable); //$NON-NLS-1$
+ }
+ else if (entity.getIdType().getPersistenceType().equals(PersistenceType.EMBEDDABLE)) {
+ SingularAttribute<?, ?> pkattr = entity.getId(entity.getIdType().getJavaType());
+ for (EmbeddableType<?> embeddable:model.getEmbeddables()) {
+ if (embeddable.getJavaType().equals(pkattr.getJavaType())) {
+ addSingularAttributes(mf, model, embeddable, entityTable);
+ ArrayList<String> keys = new ArrayList<String>();
+ for (Attribute<?, ?> attr:embeddable.getAttributes()) {
+ if (isSimpleType(attr.getJavaType())) {
+ keys.add(attr.getName());
+ }
+ else {
+ throw new TranslatorException(JPAPlugin.Util.gs(JPAPlugin.Event.TEIID14003, entityTable.getName()));
+ }
+ }
+ mf.addPrimaryKey("PK_"+pkattr.getName(), keys, entityTable);
+ break;
+ }
+ }
+ }
+ }
+ else {
+ // Composite PK. If the PK is specified with @IdClass then read its attributes,
+ // if those attributes are not found, add them as columns then as composite PK
+ ArrayList<String> keys = new ArrayList<String>();
+ for (Object obj:entity.getIdClassAttributes()) {
+ SingularAttribute<?, ?> attr = (SingularAttribute)obj;
+ addColumn(mf, attr.getName(), TypeFacility.getDataTypeName(getJavaDataType(attr.getJavaType())), entityTable);
+ keys.add(attr.getName());
+ }
+ mf.addPrimaryKey("PK_"+entity.getName(), keys, entityTable);
+ }
+ }
+
+ private Class getJavaDataType(Class type) {
+ if (type.equals(Date.class)) {
+ return java.sql.Timestamp.class;
+ }
+
+ if (type.isPrimitive()) {
+ return map.get(type); // usage
+ }
+ return type;
+ }
+
+}
Added: trunk/connectors/translator-jpa/src/main/java/org/teiid/translator/jpa/JPAPlugin.java
===================================================================
--- trunk/connectors/translator-jpa/src/main/java/org/teiid/translator/jpa/JPAPlugin.java (rev 0)
+++ trunk/connectors/translator-jpa/src/main/java/org/teiid/translator/jpa/JPAPlugin.java 2012-05-07 18:40:54 UTC (rev 4069)
@@ -0,0 +1,45 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+package org.teiid.translator.jpa;
+
+import java.util.ResourceBundle;
+
+import org.teiid.core.BundleUtil;
+
+
+public class JPAPlugin {
+
+ public static final String PLUGIN_ID = "org.teiid.translator.jpa" ; //$NON-NLS-1$
+
+ private static final String BUNDLE_NAME = PLUGIN_ID + ".i18n"; //$NON-NLS-1$
+ public static final BundleUtil Util = new BundleUtil(PLUGIN_ID,BUNDLE_NAME,ResourceBundle.getBundle(BUNDLE_NAME));
+
+ public static enum Event implements BundleUtil.Event{
+ TEIID14001,
+ TEIID14002,
+ TEIID14003,
+ TEIID14004,
+ TEIID14005,
+ TEIID14006,
+ TEIID14007
+ }
+}
Added: trunk/connectors/translator-jpa/src/main/java/org/teiid/translator/jpa/JPQLBaseExecution.java
===================================================================
--- trunk/connectors/translator-jpa/src/main/java/org/teiid/translator/jpa/JPQLBaseExecution.java (rev 0)
+++ trunk/connectors/translator-jpa/src/main/java/org/teiid/translator/jpa/JPQLBaseExecution.java 2012-05-07 18:40:54 UTC (rev 4069)
@@ -0,0 +1,41 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+package org.teiid.translator.jpa;
+
+import javax.persistence.EntityManager;
+
+import org.teiid.metadata.RuntimeMetadata;
+import org.teiid.translator.ExecutionContext;
+
+public class JPQLBaseExecution {
+
+ protected ExecutionContext executionContext;
+ protected RuntimeMetadata metadata;
+ protected EntityManager enityManager;
+
+ protected JPQLBaseExecution(ExecutionContext executionContext, RuntimeMetadata metadata, EntityManager em) {
+ this.executionContext = executionContext;
+ this.metadata = metadata;
+ this.enityManager = em;
+ }
+
+}
Added: trunk/connectors/translator-jpa/src/main/java/org/teiid/translator/jpa/JPQLQueryExecution.java
===================================================================
--- trunk/connectors/translator-jpa/src/main/java/org/teiid/translator/jpa/JPQLQueryExecution.java (rev 0)
+++ trunk/connectors/translator-jpa/src/main/java/org/teiid/translator/jpa/JPQLQueryExecution.java 2012-05-07 18:40:54 UTC (rev 4069)
@@ -0,0 +1,86 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+package org.teiid.translator.jpa;
+
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+
+import org.teiid.language.QueryExpression;
+import org.teiid.language.Select;
+import org.teiid.logging.LogConstants;
+import org.teiid.logging.LogManager;
+import org.teiid.metadata.RuntimeMetadata;
+import org.teiid.translator.DataNotAvailableException;
+import org.teiid.translator.ExecutionContext;
+import org.teiid.translator.ResultSetExecution;
+import org.teiid.translator.TranslatorException;
+
+public class JPQLQueryExecution extends JPQLBaseExecution implements ResultSetExecution {
+ private QueryExpression command;
+ private Iterator resultsIterator;
+ private JPA2ExecutionFactory executionFactory;
+
+ public JPQLQueryExecution(JPA2ExecutionFactory executionFactory, QueryExpression command, ExecutionContext executionContext, RuntimeMetadata metadata, EntityManager em) {
+ super(executionContext, metadata, em);
+ this.command = command;
+ this.executionFactory = executionFactory;
+ }
+
+ @Override
+ public void execute() throws TranslatorException {
+ String jpql = JPQLSelectVisitor.getJPQLString((Select)this.command, this.executionFactory, this.metadata);
+
+ LogManager.logTrace(LogConstants.CTX_CONNECTOR, "JPA Source-Query:", jpql); //$NON-NLS-1$
+
+ Query query = this.enityManager.createQuery(jpql);
+ List results = query.getResultList();
+ this.resultsIterator = results.iterator();
+ }
+
+ @Override
+ public List<?> next() throws TranslatorException, DataNotAvailableException {
+ if (this.resultsIterator != null && this.resultsIterator.hasNext()) {
+ Object obj = this.resultsIterator.next();
+ if (obj instanceof Object[]) {
+ return Arrays.asList((Object[])obj);
+ }
+ return Arrays.asList(obj);
+ }
+ return null;
+ }
+
+ @Override
+ public void close() {
+ // no close
+ this.resultsIterator = null;
+
+ }
+
+ @Override
+ public void cancel() throws TranslatorException {
+ // no cancel
+ }
+}
Added: trunk/connectors/translator-jpa/src/main/java/org/teiid/translator/jpa/JPQLSelectVisitor.java
===================================================================
--- trunk/connectors/translator-jpa/src/main/java/org/teiid/translator/jpa/JPQLSelectVisitor.java (rev 0)
+++ trunk/connectors/translator-jpa/src/main/java/org/teiid/translator/jpa/JPQLSelectVisitor.java 2012-05-07 18:40:54 UTC (rev 4069)
@@ -0,0 +1,448 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+package org.teiid.translator.jpa;
+
+import static org.teiid.language.SQLConstants.Reserved.*;
+
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.teiid.language.*;
+import org.teiid.language.Join.JoinType;
+import org.teiid.language.SQLConstants.Tokens;
+import org.teiid.language.visitor.HierarchyVisitor;
+import org.teiid.language.visitor.SQLStringVisitor;
+import org.teiid.metadata.AbstractMetadataRecord;
+import org.teiid.metadata.ForeignKey;
+import org.teiid.metadata.RuntimeMetadata;
+import org.teiid.metadata.Table;
+import org.teiid.translator.TranslatorException;
+/**
+ * This visitor converts the Teiid command into JPQL string
+ */
+public class JPQLSelectVisitor extends HierarchyVisitor {
+ protected JPA2ExecutionFactory executionFactory;
+ protected static final String UNDEFINED = "<undefined>"; //$NON-NLS-1$
+ private LinkedList<JoinTable> joins = new LinkedList<JoinTable>();
+ protected ArrayList<TranslatorException> exceptions = new ArrayList<TranslatorException>();
+ protected LinkedHashMap<String, NamedTable> implicitGroups = new LinkedHashMap<String, NamedTable>();
+ protected AtomicInteger aliasCounter = new AtomicInteger(0);
+ protected RuntimeMetadata metadata;
+
+ public JPQLSelectVisitor(JPA2ExecutionFactory executionFactory, RuntimeMetadata metadata) {
+ super(false);
+ this.executionFactory = executionFactory;
+ this.metadata = metadata;
+ }
+
+ public static String getJPQLString(Select obj, JPA2ExecutionFactory executionFactory, RuntimeMetadata metadata) throws TranslatorException {
+ JPQLSelectVisitor visitor = new JPQLSelectVisitor(executionFactory, metadata);
+
+ visitor.visitNode(obj);
+
+ if (!visitor.exceptions.isEmpty()) {
+ throw visitor.exceptions.get(0);
+ }
+
+ return visitor.convertToQuery(obj);
+ }
+
+ private String convertToQuery(Select obj) {
+ JPQLSelectStringVisitor visitor = new JPQLSelectStringVisitor(this);
+ visitor.visitNode(obj);
+ return visitor.toString();
+ }
+
+ @Override
+ public void visit(Select obj) {
+ visitNodes(obj.getDerivedColumns());
+ visitNodes(obj.getFrom());
+ visitNode(obj.getWhere());
+ visitNode(obj.getGroupBy());
+ visitNode(obj.getHaving());
+ visitNode(obj.getOrderBy());
+ }
+
+ @Override
+ public void visit(ColumnReference obj) {
+ AbstractMetadataRecord record = obj.getMetadataObject();
+ if (record != null) {
+ String name = record.getProperty(JPAMetadataProcessor.KEY_ASSOSIATED_WITH_FOREIGN_TABLE, false);
+ if (name != null) {
+ try {
+ Table t = this.metadata.getTable(name);
+ if (this.implicitGroups.get(name) == null) {
+ this.implicitGroups.put(name, new NamedTable(t.getName(), "J_"+this.aliasCounter.getAndIncrement(), t)); //$NON-NLS-1$
+ }
+ } catch (TranslatorException e) {
+ exceptions.add(e);
+ }
+ }
+ }
+ }
+
+ private boolean alreadyInJoin(String tableName) {
+ for(JoinTable joinTable:this.joins) {
+ if ((joinTable.left != null && joinTable.left.getMetadataObject().getFullName().equals(tableName))
+ || (joinTable.right != null && joinTable.right.getMetadataObject().getFullName().equals(tableName))) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public void visit(NamedTable obj) {
+ if (implicitGroups.isEmpty()) {
+ this.joins.add(new JoinTable(obj, null, JoinType.INNER_JOIN));
+ }
+ else {
+ for (NamedTable table:this.implicitGroups.values()) {
+ this.joins.add(new JoinTable(obj, table, JoinType.INNER_JOIN));
+ }
+ }
+ }
+
+ @Override
+ public void visit(Join obj) {
+ try {
+ handleJoin(obj);
+ for (NamedTable table:this.implicitGroups.values()) {
+ NamedTable parent = findParent(table);
+ if (parent != null) {
+ if (!alreadyInJoin(table.getMetadataObject().getFullName())) {
+ this.joins.add(new JoinTable(parent, table, JoinType.INNER_JOIN));
+ }
+ }
+ else {
+ exceptions.add(new TranslatorException(JPAPlugin.Util.gs(JPAPlugin.Event.TEIID14004, table.getName())));
+ }
+ }
+ } catch (TranslatorException e) {
+ exceptions.add(e);
+ }
+ }
+
+ private NamedTable findParent(NamedTable child) {
+ for (JoinTable jt:this.joins) {
+ if (jt.getParent() != null) {
+ if (isParentOf(jt.getParent(), child)) {
+ return jt.getParent();
+ }
+ }
+
+ if (jt.getChild() != null) {
+ if (isParentOf(jt.getChild(), child)) {
+ return jt.getChild();
+ }
+ }
+ }
+ return null;
+ }
+
+ private JoinTable handleJoin(Join obj) throws TranslatorException {
+ TableReference left = obj.getLeftItem();
+ TableReference right = obj.getRightItem();
+
+ if ((left instanceof NamedTable) && (right instanceof NamedTable)) {
+ JoinTable join = handleJoin(obj.getJoinType(), left, right, true);
+ this.joins.add(join);
+ return join;
+ }
+
+ JoinTable leftJoin = null;
+ if (left instanceof Join) {
+ leftJoin = handleJoin((Join)left);
+ if (right instanceof NamedTable) {
+ JoinTable join = handleJoin(obj.getJoinType(), leftJoin, (NamedTable)right);
+ this.joins.add(join);
+ return join;
+ }
+ }
+
+ JoinTable rightJoin = null;
+ if (right instanceof Join) {
+ rightJoin = handleJoin((Join)right);
+ if (left instanceof NamedTable) {
+ JoinTable join = handleJoin(obj.getJoinType(), (NamedTable)left, rightJoin);
+ this.joins.add(join);
+ return join;
+ }
+ }
+ throw new TranslatorException(JPAPlugin.Util.gs(JPAPlugin.Event.TEIID14005));
+ }
+
+ private JoinTable handleJoin(Join.JoinType joinType, JoinTable left, NamedTable right) throws TranslatorException {
+ // first we need to find correct parent for the right
+ JoinTable withParent = handleJoin(joinType, left.getParent(), right, false);
+ JoinTable withChild = handleJoin(joinType, left.getChild(), right, false);
+
+ NamedTable parent = (withParent.getParent() != null)?withParent.getParent():withChild.getParent();
+ if (parent != null) {
+ return handleJoin(joinType, parent, right, true);
+ }
+ throw new TranslatorException(JPAPlugin.Util.gs(JPAPlugin.Event.TEIID14006));
+ }
+
+ private JoinTable handleJoin(Join.JoinType joinType, NamedTable left, JoinTable right) throws TranslatorException {
+ // first we need to find correct parent for the left
+ JoinTable withParent = handleJoin(joinType, left, right.getParent(), false);
+ JoinTable withChild = handleJoin(joinType, left, right.getChild(), false);
+
+ NamedTable parent = (withParent.getParent() != null)?withParent.getParent():withChild.getParent();
+ if (parent != null) {
+ return handleJoin(joinType, left, parent, true);
+ }
+ throw new TranslatorException(JPAPlugin.Util.gs(JPAPlugin.Event.TEIID14006));
+ }
+
+ private JoinTable handleJoin(Join.JoinType joinType, TableReference left, TableReference right, boolean fixCorrelatedNames) {
+ // both sides are named tables
+ NamedTable leftTable = (NamedTable)left;
+ NamedTable rightTable = (NamedTable)right;
+ JoinTable joinTable = new JoinTable(leftTable, rightTable, joinType);
+
+ if (fixCorrelatedNames) {
+ // fix left table's correleated name
+ NamedTable table = this.implicitGroups.get(leftTable.getMetadataObject().getFullName());
+ if (table != null) {
+ table.setCorrelationName(leftTable.getCorrelationName());
+ }
+
+ // fix right table's correleated name
+ table = this.implicitGroups.get(rightTable.getMetadataObject().getFullName());
+ if (table != null) {
+ table.setCorrelationName(rightTable.getCorrelationName());
+ }
+ }
+ return joinTable;
+ }
+
+ private boolean isParentOf(NamedTable parent, NamedTable child) {
+ for (ForeignKey fk:parent.getMetadataObject().getForeignKeys()){
+ if (fk.getReferenceTableName().equals(child.getMetadataObject().getName())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ static class JoinTable {
+ NamedTable parent;
+ NamedTable child;
+ NamedTable left;
+ NamedTable right;
+ String childAttributeName;
+ String parentAttributeName;
+ JoinType joinType;
+
+ JoinTable(NamedTable customer, NamedTable address, JoinType type) {
+ this.left = customer;
+ this.right = address;
+ this.joinType = type;
+ if (address == null) {
+ this.parent = customer;
+ this.parentAttributeName = customer.getName();
+ }
+ else {
+ for (ForeignKey fk:customer.getMetadataObject().getForeignKeys()){
+ if (fk.getReferenceTableName().equals(address.getMetadataObject().getName())) {
+ this.parent = customer;
+ this.child = address;
+ this.childAttributeName = fk.getNameInSource();
+ this.parentAttributeName = customer.getName();
+ }
+ }
+ if (this.parent == null) {
+ for (ForeignKey fk:address.getMetadataObject().getForeignKeys()){
+ if (fk.getReferenceTableName().equals(customer.getMetadataObject().getName())) {
+ this.parent = address;
+ this.child = customer;
+ this.childAttributeName = fk.getNameInSource();
+ this.parentAttributeName = customer.getName();
+ }
+ }
+ }
+ }
+ }
+
+ NamedTable getParent() {
+ return this.parent;
+ }
+
+ NamedTable getChild() {
+ return this.child;
+ }
+
+ NamedTable getLeft() {
+ return this.left;
+ }
+
+ NamedTable getRight() {
+ return this.right;
+ }
+
+ String childAttributeName() {
+ return this.childAttributeName;
+ }
+
+ String parentAttributeName() {
+ return this.parentAttributeName;
+ }
+
+ public boolean isLeftParent() {
+ return this.left == this.parent;
+ }
+ }
+
+
+ static class JPQLSelectStringVisitor extends SQLStringVisitor {
+ private JPQLSelectVisitor visitor;
+
+ public JPQLSelectStringVisitor(JPQLSelectVisitor visitor) {
+ this.visitor = visitor;
+ }
+
+ @Override
+ public void visit(Select obj) {
+
+ buffer.append(SELECT).append(Tokens.SPACE);
+
+ if (obj.isDistinct()) {
+ buffer.append(DISTINCT).append(Tokens.SPACE);
+ }
+
+ append(obj.getDerivedColumns());
+
+ if (obj.getFrom() != null && !obj.getFrom().isEmpty()) {
+ buffer.append(Tokens.SPACE).append(FROM).append(Tokens.SPACE);
+ append(obj.getFrom());
+ }
+
+ if (obj.getWhere() != null) {
+ buffer.append(Tokens.SPACE)
+ .append(WHERE)
+ .append(Tokens.SPACE);
+ append(obj.getWhere());
+ }
+ if (obj.getGroupBy() != null) {
+ buffer.append(Tokens.SPACE);
+ append(obj.getGroupBy());
+ }
+ if (obj.getHaving() != null) {
+ buffer.append(Tokens.SPACE)
+ .append(HAVING)
+ .append(Tokens.SPACE);
+ append(obj.getHaving());
+ }
+ if (obj.getOrderBy() != null) {
+ buffer.append(Tokens.SPACE);
+ append(obj.getOrderBy());
+ }
+ }
+
+ @Override
+ public void visit(ColumnReference column) {
+ AbstractMetadataRecord record = column.getMetadataObject();
+ if (record != null) {
+ String name = record.getProperty(JPAMetadataProcessor.KEY_ASSOSIATED_WITH_FOREIGN_TABLE, false);
+ if (name == null) {
+ buffer.append(column.getTable().getCorrelationName()).append(Tokens.DOT).append(column.getMetadataObject().getName());
+ }
+ else {
+ buffer.append(this.visitor.implicitGroups.get(name).getCorrelationName()).append(Tokens.DOT).append(column.getMetadataObject().getName());
+ }
+ }
+ else {
+ buffer.append(column.getName());
+ }
+ }
+
+ @Override
+ public void visit(Join obj) {
+ addFromClause();
+ }
+
+ @Override
+ public void visit(Function func) {
+ if (visitor.executionFactory.getFunctionModifiers().containsKey(func.getName())) {
+ visitor.executionFactory.getFunctionModifiers().get(func.getName()).translate(func);
+ }
+ super.visit(func);
+ }
+
+ @Override
+ public void visit(NamedTable obj) {
+ addFromClause();
+ }
+
+ private void addFromClause() {
+ boolean first = true;
+ for (JoinTable joinTable:this.visitor.joins) {
+ if (!joinTable.isLeftParent() && joinTable.joinType == JoinType.LEFT_OUTER_JOIN) {
+ joinTable.joinType = JoinType.RIGHT_OUTER_JOIN;
+ }
+ if (first) {
+ buffer.append(joinTable.getParent().getName());
+ buffer.append(Tokens.SPACE);
+ buffer.append(AS).append(Tokens.SPACE);
+ buffer.append(joinTable.getParent().getCorrelationName());
+ first = false;
+ }
+ if (joinTable.getChild() != null) {
+ buffer.append(Tokens.SPACE);
+ switch(joinTable.joinType) {
+ case CROSS_JOIN:
+ buffer.append(CROSS);
+ break;
+ case FULL_OUTER_JOIN:
+ buffer.append(FULL)
+ .append(Tokens.SPACE)
+ .append(OUTER);
+ break;
+ case INNER_JOIN:
+ buffer.append(INNER);
+ break;
+ case LEFT_OUTER_JOIN:
+ buffer.append(LEFT)
+ .append(Tokens.SPACE)
+ .append(OUTER);
+ break;
+ case RIGHT_OUTER_JOIN:
+ buffer.append(RIGHT)
+ .append(Tokens.SPACE)
+ .append(OUTER);
+ break;
+ default: buffer.append(UNDEFINED);
+ }
+ buffer.append(Tokens.SPACE).append(JOIN).append(Tokens.SPACE);
+ buffer.append(joinTable.getParent().getCorrelationName()).append(Tokens.DOT).append(joinTable.childAttributeName());
+ buffer.append(Tokens.SPACE);
+ buffer.append(AS).append(Tokens.SPACE);
+ buffer.append(joinTable.getChild().getCorrelationName());
+ }
+ }
+ }
+ }
+}
Added: trunk/connectors/translator-jpa/src/main/java/org/teiid/translator/jpa/JPQLUpdateExecution.java
===================================================================
--- trunk/connectors/translator-jpa/src/main/java/org/teiid/translator/jpa/JPQLUpdateExecution.java (rev 0)
+++ trunk/connectors/translator-jpa/src/main/java/org/teiid/translator/jpa/JPQLUpdateExecution.java 2012-05-07 18:40:54 UTC (rev 4069)
@@ -0,0 +1,124 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+package org.teiid.translator.jpa;
+
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+
+import org.teiid.core.TeiidException;
+import org.teiid.core.util.PropertiesUtils;
+import org.teiid.core.util.ReflectionHelper;
+import org.teiid.language.*;
+import org.teiid.logging.LogConstants;
+import org.teiid.logging.LogManager;
+import org.teiid.metadata.Column;
+import org.teiid.metadata.RuntimeMetadata;
+import org.teiid.translator.DataNotAvailableException;
+import org.teiid.translator.ExecutionContext;
+import org.teiid.translator.TranslatorException;
+import org.teiid.translator.UpdateExecution;
+
+public class JPQLUpdateExecution extends JPQLBaseExecution implements UpdateExecution {
+ private Command command;
+ private int[] results;
+
+ public JPQLUpdateExecution(Command command, ExecutionContext executionContext, RuntimeMetadata metadata, EntityManager em) {
+ super(executionContext, metadata, em);
+ this.command = command;
+ }
+
+ @Override
+ public void execute() throws TranslatorException {
+ if (command instanceof BatchedUpdates) {
+ BatchedUpdates updates = (BatchedUpdates)this.command;
+ this.results = new int[updates.getUpdateCommands().size()];
+ int index = 0;
+ for (Command cmd:updates.getUpdateCommands()) {
+ this.results[index++] = executeUpdate(cmd);
+ }
+ }
+ else if (this.command instanceof Insert) {
+ this.results = new int[1];
+ Object entity = handleInsert((Insert)this.command);
+ this.enityManager.merge(entity);
+ this.results[0] = 1;
+ }
+ else {
+ // update or delete
+ this.results = new int[1];
+ this.results[0] = executeUpdate(this.command);
+ }
+ }
+
+ private int executeUpdate(Command cmd) throws TranslatorException {
+ String jpql = JPQLUpdateQueryVisitor.getJPQLString(cmd);
+ LogManager.logTrace(LogConstants.CTX_CONNECTOR, "JPA Source-Query:", jpql); //$NON-NLS-1$
+ Query query = this.enityManager.createQuery(jpql);
+ return query.executeUpdate();
+ }
+
+ @Override
+ public int[] getUpdateCounts() throws DataNotAvailableException, TranslatorException {
+ return this.results;
+ }
+
+ @Override
+ public void close() {
+ }
+
+ @Override
+ public void cancel() throws TranslatorException {
+ }
+
+ private Object handleInsert(Insert insert) throws TranslatorException {
+ try {
+ String entityClassName = insert.getTable().getMetadataObject().getProperty(JPAMetadataProcessor.ENTITYCLASS, false);
+ Object entity = ReflectionHelper.create(entityClassName, null, this.executionContext.getCommandContext().getVDBClassLoader());
+
+ List<ColumnReference> columns = insert.getColumns();
+ List<Expression> values = ((ExpressionValueSource)insert.getValueSource()).getValues();
+ if(columns.size() != values.size()) {
+ throw new TranslatorException(JPAPlugin.Util.gs(JPAPlugin.Event.TEIID14007));
+ }
+ for(int i = 0; i < columns.size(); i++) {
+ Column column = columns.get(i).getMetadataObject();
+ Object value = values.get(i);
+
+ // do not add the derived columns
+ String name = column.getProperty(JPAMetadataProcessor.KEY_ASSOSIATED_WITH_FOREIGN_TABLE, false);
+ if (name == null) {
+ if(value instanceof Literal) {
+ Literal literalValue = (Literal)value;
+ PropertiesUtils.setBeanProperty(entity, column.getName(), literalValue.getValue());
+ } else {
+ PropertiesUtils.setBeanProperty(entity, column.getName(), value);
+ }
+ }
+ }
+ return entity;
+ } catch (TeiidException e) {
+ throw new TranslatorException(e);
+ }
+ }
+}
Added: trunk/connectors/translator-jpa/src/main/java/org/teiid/translator/jpa/JPQLUpdateQueryVisitor.java
===================================================================
--- trunk/connectors/translator-jpa/src/main/java/org/teiid/translator/jpa/JPQLUpdateQueryVisitor.java (rev 0)
+++ trunk/connectors/translator-jpa/src/main/java/org/teiid/translator/jpa/JPQLUpdateQueryVisitor.java 2012-05-07 18:40:54 UTC (rev 4069)
@@ -0,0 +1,100 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+package org.teiid.translator.jpa;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.teiid.language.ColumnReference;
+import org.teiid.language.Command;
+import org.teiid.language.NamedTable;
+import org.teiid.language.SQLConstants.Tokens;
+import org.teiid.language.visitor.HierarchyVisitor;
+import org.teiid.language.visitor.SQLStringVisitor;
+import org.teiid.metadata.AbstractMetadataRecord;
+import org.teiid.translator.TranslatorException;
+
+public class JPQLUpdateQueryVisitor extends HierarchyVisitor {
+ protected ArrayList<TranslatorException> exceptions = new ArrayList<TranslatorException>();
+ protected AtomicInteger aliasCounter = new AtomicInteger(0);
+ protected HashMap<String, String> correlatedName = new HashMap<String, String>();
+
+ public JPQLUpdateQueryVisitor() {
+ super(false);
+ }
+
+ public static String getJPQLString(Command obj) throws TranslatorException {
+ JPQLUpdateQueryVisitor visitor = new JPQLUpdateQueryVisitor();
+
+ visitor.visitNode(obj);
+
+ if (!visitor.exceptions.isEmpty()) {
+ throw visitor.exceptions.get(0);
+ }
+
+ return visitor.convertToQuery(obj);
+ }
+
+ private String convertToQuery(Command obj) {
+ JPQLUpdateStringVisitor visitor = new JPQLUpdateStringVisitor(this);
+ visitor.visitNode(obj);
+ return visitor.toString();
+ }
+
+ @Override
+ public void visit(NamedTable obj) {
+ if (obj.getCorrelationName() == null) {
+ String aliasName = "ql_"+this.aliasCounter.getAndIncrement(); //$NON-NLS-1$
+ this.correlatedName.put(obj.getMetadataObject().getName(), aliasName);
+ obj.setCorrelationName(aliasName);
+ }
+ else {
+ this.correlatedName.put(obj.getMetadataObject().getName(), obj.getCorrelationName());
+ }
+ }
+
+ static class JPQLUpdateStringVisitor extends SQLStringVisitor {
+ private JPQLUpdateQueryVisitor visitor;
+
+ public JPQLUpdateStringVisitor(JPQLUpdateQueryVisitor visitor) {
+ this.visitor = visitor;
+ }
+
+ @Override
+ public void visit(ColumnReference column) {
+ AbstractMetadataRecord record = column.getMetadataObject();
+ if (record != null) {
+ String name = record.getProperty(JPAMetadataProcessor.KEY_ASSOSIATED_WITH_FOREIGN_TABLE, false);
+ if (name == null) {
+ buffer.append(this.visitor.correlatedName.get(column.getTable().getMetadataObject().getName())).append(Tokens.DOT).append(column.getMetadataObject().getName());
+ }
+ else {
+ buffer.append(this.visitor.correlatedName.get(name)).append(Tokens.DOT).append(column.getMetadataObject().getName());
+ }
+ }
+ else {
+ buffer.append(column.getName());
+ }
+ }
+ }
+}
Added: trunk/connectors/translator-jpa/src/main/resources/META-INF/MANIFEST.MF
===================================================================
--- trunk/connectors/translator-jpa/src/main/resources/META-INF/MANIFEST.MF (rev 0)
+++ trunk/connectors/translator-jpa/src/main/resources/META-INF/MANIFEST.MF 2012-05-07 18:40:54 UTC (rev 4069)
@@ -0,0 +1 @@
+Dependencies: org.hibernate,org.jboss.teiid.translator.jdbc
Added: trunk/connectors/translator-jpa/src/main/resources/META-INF/services/org.teiid.translator.ExecutionFactory
===================================================================
--- trunk/connectors/translator-jpa/src/main/resources/META-INF/services/org.teiid.translator.ExecutionFactory (rev 0)
+++ trunk/connectors/translator-jpa/src/main/resources/META-INF/services/org.teiid.translator.ExecutionFactory 2012-05-07 18:40:54 UTC (rev 4069)
@@ -0,0 +1 @@
+org.teiid.translator.jpa.JPA2ExecutionFactory
\ No newline at end of file
Added: trunk/connectors/translator-jpa/src/main/resources/org/teiid/translator/jpa/i18n.properties
===================================================================
--- trunk/connectors/translator-jpa/src/main/resources/org/teiid/translator/jpa/i18n.properties (rev 0)
+++ trunk/connectors/translator-jpa/src/main/resources/org/teiid/translator/jpa/i18n.properties 2012-05-07 18:40:54 UTC (rev 4069)
@@ -0,0 +1,7 @@
+TEIID14001=PK on table {0} not found
+TEIID14002=Attribute can not be resolved:{0}
+TEIID14003=Embedded class has entity type based pk, not allowed on {0}
+TEIID14004=No parent table found for {0}
+TEIID14005=Bushy joins are not supported.
+TEIID14006=Unsupported join semantics, join can only be done where relationship exists
+TEIID14007=Columns.size and values.size are not the same
\ No newline at end of file
Added: trunk/connectors/translator-jpa/src/test/java/org/teiid/translator/jpa/TestJSelectJPQLVisitor.java
===================================================================
--- trunk/connectors/translator-jpa/src/test/java/org/teiid/translator/jpa/TestJSelectJPQLVisitor.java (rev 0)
+++ trunk/connectors/translator-jpa/src/test/java/org/teiid/translator/jpa/TestJSelectJPQLVisitor.java 2012-05-07 18:40:54 UTC (rev 4069)
@@ -0,0 +1,91 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+package org.teiid.translator.jpa;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.teiid.cdk.api.TranslationUtility;
+import org.teiid.core.util.UnitTestUtil;
+import org.teiid.language.Select;
+import org.teiid.query.metadata.TransformationMetadata;
+import org.teiid.query.unittest.RealMetadataFactory;
+
+@SuppressWarnings("nls")
+public class TestJSelectJPQLVisitor {
+ private JPA2ExecutionFactory jpaTranslator;
+ private TranslationUtility utility;
+
+ @Before
+ public void setUp() throws Exception {
+ jpaTranslator = new JPA2ExecutionFactory();
+ jpaTranslator.start();
+
+ TransformationMetadata metadata = RealMetadataFactory.fromDDL(UnitTestUtil.getTestDataFile("sakila.ddl"), "sakila", "sakila");
+ utility = new TranslationUtility(metadata);
+
+ }
+
+ private void helpExecute(String query, String expected) throws Exception {
+ Select cmd = (Select)this.utility.parseCommand(query);
+ String jpaCommand = JPQLSelectVisitor.getJPQLString(cmd, jpaTranslator, utility.createRuntimeMetadata());
+ assertEquals(expected, jpaCommand);
+ }
+
+ @Test
+ public void testProjectionBasedJoin() throws Exception {
+ helpExecute("select * from customer as c", "SELECT c.customer_id, J_0.store_id, c.first_name, c.last_name, c.email, J_1.address_id, c.active, c.create_date, c.last_update FROM customer AS c INNER JOIN c.store AS J_0 INNER JOIN c.address AS J_1");
+ }
+
+ @Test
+ public void testExplicitJoinJoin() throws Exception {
+ helpExecute("select c.first_name, c.last_name, a.address_id FROM customer c join address a on c.address_id=a.address_id",
+ "SELECT c.first_name, c.last_name, a.address_id FROM customer AS c INNER JOIN c.address AS a");
+ }
+
+ @Test
+ public void testSimpleSelect() throws Exception {
+ helpExecute("select c.first_name, c.last_name FROM customer c order by last_name",
+ "SELECT c.first_name, c.last_name FROM customer AS c ORDER BY c.last_name");
+ }
+
+ @Test
+ public void testFunctionsSelect() throws Exception {
+ helpExecute("select concat(lcase(first_name), last_Name) from customer as c",
+ "SELECT concat(lower(c.first_name), c.last_name) FROM customer AS c");
+ }
+
+ @Test
+ public void testRightJoinRewriteSelect() throws Exception {
+ helpExecute("select c.first_name, c.last_name, c.address_id, a.phone from customer c right join address a on c.address_Id=a.address_Id",
+ "SELECT c.first_name, c.last_name, a.address_id, a.phone FROM customer AS c RIGHT OUTER JOIN c.address AS a");
+ }
+
+ @Test
+ public void testRightandinnerJoinRewriteSelect() throws Exception {
+ helpExecute("select c.first_name, c.last_name, a.address_id, a.phone, ci.city from customer c join address a on c.address_Id=a.address_Id right join city ci on ci.city_id = a.city_id where c.last_Name='MYERS' OR c.last_Name='TALBERT' order by c.first_Name",
+ "SELECT c.first_name, c.last_name, a.address_id, a.phone, ci.city FROM customer AS c INNER JOIN c.address AS a RIGHT OUTER JOIN a.city AS ci WHERE c.last_name IN ('TALBERT', 'MYERS') ORDER BY c.first_name");
+ }
+
+ // needs one with composite PK
+}
Added: trunk/connectors/translator-jpa/src/test/resources/sakila.ddl
===================================================================
--- trunk/connectors/translator-jpa/src/test/resources/sakila.ddl (rev 0)
+++ trunk/connectors/translator-jpa/src/test/resources/sakila.ddl 2012-05-07 18:40:54 UTC (rev 4069)
@@ -0,0 +1,69 @@
+CREATE FOREIGN TABLE country (
+ country_id integer NOT NULL AUTO_INCREMENT,
+ country varchar(50) NOT NULL,
+ last_update timestamp NOT NULL
+ CONSTRAINT PRIMARY KEY (country_id)
+);
+
+CREATE FOREIGN TABLE city (
+ city_id integer NOT NULL AUTO_INCREMENT,
+ city varchar(50) NOT NULL,
+ country_id integer NOT NULL OPTIONS (assosiated_with_table 'sakila.country'),
+ last_update timestamp NOT NULL
+ CONSTRAINT PRIMARY KEY (city_id),
+ FOREIGN KEY (country_id) REFERENCES country (country_id) OPTIONS(NAMEINSOURCE 'country')
+);
+
+CREATE FOREIGN TABLE address (
+ address_id integer NOT NULL AUTO_INCREMENT,
+ address varchar(50) NOT NULL,
+ address2 varchar(50),
+ district varchar(20) NOT NULL,
+ city_id integer NOT NULL OPTIONS (assosiated_with_table 'sakila.city'),
+ postal_code varchar(10),
+ phone varchar(20) NOT NULL,
+ last_update timestamp NOT NULL
+ CONSTRAINT PRIMARY KEY (address_id),
+ FOREIGN KEY (city_id) REFERENCES city (city_id) OPTIONS(NAMEINSOURCE 'city')
+);
+
+CREATE FOREIGN TABLE staff (
+ staff_id byte NOT NULL AUTO_INCREMENT,
+ first_name varchar(45) NOT NULL,
+ last_name varchar(45) NOT NULL,
+ address_id integer NOT NULL OPTIONS (assosiated_with_table 'sakila.address'),
+ email varchar(50),
+ store_id byte NOT NULL OPTIONS (assosiated_with_table 'sakila.store'),
+ active boolean NOT NULL,
+ username varchar(16) NOT NULL,
+ password varchar(40),
+ last_update timestamp
+ CONSTRAINT PRIMARY KEY (staff_id),
+ FOREIGN KEY (store_id) REFERENCES store (store_id) OPTIONS(NAMEINSOURCE 'store'),
+ FOREIGN KEY (address_id) REFERENCES address (address_id) OPTIONS(NAMEINSOURCE 'address')
+);
+
+CREATE FOREIGN TABLE store (
+ store_id byte NOT NULL AUTO_INCREMENT,
+ manager_staff_id byte NOT NULL OPTIONS (assosiated_with_table 'sakila.staff'),
+ address_id integer NOT NULL OPTIONS (assosiated_with_table 'sakila.store'),
+ last_update timestamp NOT NULL
+ CONSTRAINT PRIMARY KEY (store_id),
+ FOREIGN KEY (manager_staff_id) REFERENCES staff (staff_id) OPTIONS(NAMEINSOURCE 'staff'),
+ FOREIGN KEY (address_id) REFERENCES address (address_id) OPTIONS(NAMEINSOURCE 'address')
+);
+
+CREATE FOREIGN TABLE customer (
+ customer_id integer NOT NULL AUTO_INCREMENT,
+ store_id byte NOT NULL OPTIONS (assosiated_with_table 'sakila.store'),
+ first_name varchar(45) NOT NULL,
+ last_name varchar(45) NOT NULL,
+ email varchar(50),
+ address_id integer NOT NULL OPTIONS (assosiated_with_table 'sakila.address'),
+ active boolean NOT NULL,
+ create_date timestamp NOT NULL,
+ last_update timestamp
+ constraint PRIMARY KEY (customer_id),
+ FOREIGN KEY (address_id) REFERENCES address (address_id) OPTIONS(NAMEINSOURCE 'address'),
+ FOREIGN KEY (store_id) REFERENCES store (store_id) OPTIONS(NAMEINSOURCE 'store')
+);
\ No newline at end of file
Added: trunk/connectors/translator-jpa/target/classes/META-INF/MANIFEST.MF
===================================================================
--- trunk/connectors/translator-jpa/target/classes/META-INF/MANIFEST.MF (rev 0)
+++ trunk/connectors/translator-jpa/target/classes/META-INF/MANIFEST.MF 2012-05-07 18:40:54 UTC (rev 4069)
@@ -0,0 +1 @@
+Dependencies: org.hibernate,org.jboss.teiid.translator.jdbc
Property changes on: trunk/connectors/translator-jpa/target/classes/META-INF/MANIFEST.MF
___________________________________________________________________
Added: svn:mime-type
+ text/plain
11 years, 10 months
teiid SVN: r4068 - branches/7.7.x/connectors.
by teiid-commits@lists.jboss.org
Author: van.halbert
Date: 2012-05-07 14:28:19 -0400 (Mon, 07 May 2012)
New Revision: 4068
Modified:
branches/7.7.x/connectors/pom.xml
Log:
TEIID-1992 added connector-infinispan and translator-object to be built
Modified: branches/7.7.x/connectors/pom.xml
===================================================================
--- branches/7.7.x/connectors/pom.xml 2012-05-07 18:26:07 UTC (rev 4067)
+++ branches/7.7.x/connectors/pom.xml 2012-05-07 18:28:19 UTC (rev 4068)
@@ -88,5 +88,7 @@
<module>translator-ws</module>
<module>translator-olap</module>
<module>translator-hive</module>
+ <module>translator-object</module>
+ <module>connector-infinispan</module>
</modules>
</project>
11 years, 10 months