diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DB2Dictionary.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DB2Dictionary.java index 523b9ae543..eaea440e3a 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DB2Dictionary.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DB2Dictionary.java @@ -1023,22 +1023,30 @@ public byte[] getBytes(ResultSet rs, int column) return (byte[]) rs.getObject(column); } - int type = rs.getMetaData().getColumnType(column); - switch (type) { - case Types.BLOB: - Blob blob = getBlob(rs, column); - if (blob == null) { - return null; - } - - int length = (int) blob.length(); - if (length == 0) { - return null; - } - return blob.getBytes(1, length); - case Types.BINARY: - default: + // At this point we don't have any idea if the DB2 column was defined as + // a blob or if it was defined as CHAR for BIT DATA. + // First try as a blob, if that doesn't work, then try as CHAR for BIT DATA + // If that doesn't work, then go ahead and throw the first exception + try { + Blob blob = getBlob(rs, column); + if (blob == null) { + return null; + } + + int length = (int) blob.length(); + if (length == 0) { + return null; + } + + return blob.getBytes(1, length); + } + catch (SQLException e) { + try { return rs.getBytes(column); + } + catch (SQLException e2) { + throw e; + } } } diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/meta/AbstractCFMetaDataFactory.java b/openjpa-kernel/src/main/java/org/apache/openjpa/meta/AbstractCFMetaDataFactory.java index 16e3027798..6b06ad7656 100644 --- a/openjpa-kernel/src/main/java/org/apache/openjpa/meta/AbstractCFMetaDataFactory.java +++ b/openjpa-kernel/src/main/java/org/apache/openjpa/meta/AbstractCFMetaDataFactory.java @@ -53,6 +53,7 @@ import org.apache.openjpa.lib.meta.MetaDataIterator; import org.apache.openjpa.lib.meta.MetaDataParser; import org.apache.openjpa.lib.meta.MetaDataSerializer; +import org.apache.openjpa.lib.meta.OSGiBundleMetaDataIterator; import org.apache.openjpa.lib.meta.ResourceMetaDataIterator; import org.apache.openjpa.lib.meta.URLMetaDataIterator; import org.apache.openjpa.lib.meta.ZipFileMetaDataIterator; @@ -759,6 +760,15 @@ public File run() { } catch (PrivilegedActionException pae) { throw (IOException) pae.getException(); } + } else if ("bundle".equals(url.getProtocol())) { + + if (log.isTraceEnabled()) { + log.trace(_loc.get("scanning-osgi-bundle", url)); + } + + MetaDataIterator mdi = new OSGiBundleMetaDataIterator(url, newMetaDataFilter()); + scan(mdi, cparser, names, true, url); + } else { // Open an InputStream from the URL and sniff for a zip header. If it is, then this is // a URL with a jar-formated InputStream, as per the JPA specification. Otherwise, fall back diff --git a/openjpa-lib/pom.xml b/openjpa-lib/pom.xml index c828e61666..2ad9fe00b5 100644 --- a/openjpa-lib/pom.xml +++ b/openjpa-lib/pom.xml @@ -78,7 +78,13 @@ org.apache.geronimo.specs geronimo-validation_1.0_spec provided - + + + org.osgi + org.osgi.core + 4.2.0 + provided + diff --git a/openjpa-lib/src/main/java/org/apache/openjpa/lib/meta/OSGiBundleMetaDataIterator.java b/openjpa-lib/src/main/java/org/apache/openjpa/lib/meta/OSGiBundleMetaDataIterator.java new file mode 100644 index 0000000000..7f86ffbe40 --- /dev/null +++ b/openjpa-lib/src/main/java/org/apache/openjpa/lib/meta/OSGiBundleMetaDataIterator.java @@ -0,0 +1,130 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.openjpa.lib.meta; + +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; + +import java.io.*; +import java.net.URL; +import java.util.Enumeration; +import java.util.NoSuchElementException; + +/** + * Created by andrei on 24.07.2014. + */ +public class OSGiBundleMetaDataIterator implements MetaDataIterator, MetaDataFilter.Resource { + + private InputStream stream; + private Bundle bundle; + private Enumeration entries; + private MetaDataFilter filter; + private URL entry; + private URL last; + private byte[] buf; + + public OSGiBundleMetaDataIterator(URL bundleUrl, MetaDataFilter filter) { + + BundleContext ctx = FrameworkUtil.getBundle(OSGiBundleMetaDataIterator.class).getBundleContext(); + long bundleId = Long.parseLong(bundleUrl.getHost().substring(0, bundleUrl.getHost().indexOf("."))); + this.bundle = ctx.getBundle(bundleId); + entries = this.bundle.findEntries("/", "*.class", true); + this.filter = filter; + + } + + @Override + public boolean hasNext() throws IOException { + + if (entries == null) { + return false; + } + + if (entry != null) { + return true; + } + + last = null; + buf = null; + + if (!entries.hasMoreElements()) { + return false; + } + + URL tmp; + while ( entry == null && (entries.hasMoreElements() && (tmp = this.entries.nextElement()) != null)) { + entry = tmp; + stream = entry.openStream(); + if (filter != null && !this.filter.matches(this)) { + entry = null; + } + + } + + return entry != null; + + } + + @Override + public Object next() throws IOException { + + if (!hasNext()) { + throw new NoSuchElementException(); + } + + String name = entry.toString(); + last = entry; + entry = null; + + return name; + } + + @Override + public InputStream getInputStream() throws IOException { + if (last == null) + throw new IllegalStateException(); + + return last.openStream(); + } + + @Override + public File getFile() throws IOException { + return null; + } + + @Override + public void close() { + } + + @Override + public String getName() { + return entry.toString(); + } + + @Override + public byte[] getContent() throws IOException { + ByteArrayOutputStream bout = new ByteArrayOutputStream(); + byte[] buf = new byte[1024]; + for (int r; (r = stream.read(buf)) != -1; bout.write(buf, 0, r)) ; + buf = bout.toByteArray(); + stream.close(); + return buf; + } +}