-
-
Notifications
You must be signed in to change notification settings - Fork 99
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1668 from gritGmbH/enhancement/lob-converter-3.6
Fix issue where CustomConverter is ignored in table-driven feature mapping mode and provide exemplary implementations [3.6]
- Loading branch information
Showing
8 changed files
with
596 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
116 changes: 116 additions & 0 deletions
116
.../java/org/deegree/feature/persistence/sql/converter/AbstractStringPrimitiveConverter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
/*---------------------------------------------------------------------------- | ||
This file is part of deegree, http://deegree.org/ | ||
Copyright (C) 2001-2024 by: | ||
- Department of Geography, University of Bonn - | ||
and | ||
- lat/lon GmbH - | ||
and | ||
- grit graphische Informationstechnik Beratungsgesellschaft mbH - | ||
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., | ||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
Contact information: | ||
grit graphische Informationstechnik Beratungsgesellschaft mbH | ||
Landwehrstr. 143, 59368 Werne | ||
Germany | ||
https://www.grit.de/ | ||
lat/lon GmbH | ||
Aennchenstr. 19, 53177 Bonn | ||
Germany | ||
http://lat-lon.de/ | ||
Department of Geography, University of Bonn | ||
Prof. Dr. Klaus Greve | ||
Postfach 1147, 53001 Bonn | ||
Germany | ||
http://www.geographie.uni-bonn.de/deegree/ | ||
e-mail: info@deegree.org | ||
----------------------------------------------------------------------------*/ | ||
package org.deegree.feature.persistence.sql.converter; | ||
|
||
import static org.slf4j.LoggerFactory.getLogger; | ||
|
||
import org.deegree.commons.tom.primitive.BaseType; | ||
import org.deegree.commons.tom.primitive.PrimitiveType; | ||
import org.deegree.commons.tom.primitive.PrimitiveValue; | ||
import org.deegree.feature.persistence.sql.SQLFeatureStore; | ||
import org.deegree.feature.persistence.sql.jaxb.CustomConverterJAXB; | ||
import org.deegree.feature.persistence.sql.rules.Mapping; | ||
import org.deegree.feature.persistence.sql.rules.PrimitiveMapping; | ||
import org.slf4j.Logger; | ||
|
||
/** | ||
* Base for building a custom converter on top of primitive mappings of strings | ||
* | ||
* @see BinaryBase64PrimitiveConverter | ||
* @see BinaryDataUrlPrimitiveConverter | ||
* @see CharacterPrimitiveConverter | ||
* @author <a href="mailto:reichhelm@grit.de">Stephan Reichhelm</a> | ||
*/ | ||
public abstract class AbstractStringPrimitiveConverter implements CustomParticleConverter<PrimitiveValue> { | ||
|
||
private static final Logger LOG = getLogger(AbstractStringPrimitiveConverter.class); | ||
|
||
protected final PrimitiveType pt = new PrimitiveType(BaseType.STRING); | ||
|
||
private String column = null; | ||
|
||
protected int maxLen = 256 * 1024 * 1024; // Default limit of 256 MiB | ||
|
||
protected int sqlType; | ||
|
||
protected AbstractStringPrimitiveConverter(int defaultSqlType) { | ||
this.sqlType = defaultSqlType; | ||
} | ||
|
||
@Override | ||
public String getSelectSnippet(String tableAlias) { | ||
if (tableAlias != null) { | ||
if (column.startsWith("'") || column.contains(" ")) { | ||
return column.replace("$0", tableAlias); | ||
} | ||
return tableAlias + "." + column; | ||
} | ||
return column; | ||
} | ||
|
||
@Override | ||
public String getSetSnippet(PrimitiveValue particle) { | ||
return "?"; | ||
} | ||
|
||
@Override | ||
public void init(Mapping mapping, SQLFeatureStore fs) { | ||
if (mapping.getConverter() == null) { | ||
return; | ||
} | ||
for (CustomConverterJAXB.Param p : mapping.getConverter().getParam()) { | ||
if ("max-length".equalsIgnoreCase(p.getName())) { | ||
maxLen = Math.max(1, Integer.parseInt(p.getValue())); | ||
} | ||
if ("sql-type".equalsIgnoreCase(p.getName())) { | ||
sqlType = Integer.parseInt(p.getValue()); | ||
} | ||
} | ||
if (mapping instanceof PrimitiveMapping) { | ||
column = ((PrimitiveMapping) mapping).getMapping().toString(); | ||
} | ||
else { | ||
LOG.error("Converter cannot be used for mapping path {}", mapping.getPath()); | ||
} | ||
} | ||
|
||
} |
146 changes: 146 additions & 0 deletions
146
...in/java/org/deegree/feature/persistence/sql/converter/BinaryBase64PrimitiveConverter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
/*---------------------------------------------------------------------------- | ||
This file is part of deegree, http://deegree.org/ | ||
Copyright (C) 2001-2024 by: | ||
- Department of Geography, University of Bonn - | ||
and | ||
- lat/lon GmbH - | ||
and | ||
- grit graphische Informationstechnik Beratungsgesellschaft mbH - | ||
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., | ||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
Contact information: | ||
grit graphische Informationstechnik Beratungsgesellschaft mbH | ||
Landwehrstr. 143, 59368 Werne | ||
Germany | ||
https://www.grit.de/ | ||
lat/lon GmbH | ||
Aennchenstr. 19, 53177 Bonn | ||
Germany | ||
http://lat-lon.de/ | ||
Department of Geography, University of Bonn | ||
Prof. Dr. Klaus Greve | ||
Postfach 1147, 53001 Bonn | ||
Germany | ||
http://www.geographie.uni-bonn.de/deegree/ | ||
e-mail: info@deegree.org | ||
----------------------------------------------------------------------------*/ | ||
package org.deegree.feature.persistence.sql.converter; | ||
|
||
import static org.slf4j.LoggerFactory.getLogger; | ||
|
||
import java.io.ByteArrayInputStream; | ||
import java.io.IOException; | ||
import java.io.InputStream; | ||
import java.sql.PreparedStatement; | ||
import java.sql.ResultSet; | ||
import java.sql.SQLException; | ||
import java.sql.SQLFeatureNotSupportedException; | ||
import java.sql.Types; | ||
import java.util.Base64; | ||
import org.apache.commons.io.IOUtils; | ||
import org.deegree.commons.tom.primitive.PrimitiveValue; | ||
import org.deegree.feature.persistence.sql.SQLFeatureStore; | ||
import org.deegree.feature.persistence.sql.rules.Mapping; | ||
import org.slf4j.Logger; | ||
|
||
/** | ||
* Converts binary database columns from/to primitive strings encoded as Base64 | ||
* <p> | ||
* Note that the maximum length of allowed data is limited to prevent Denial of Service | ||
* Attacks. The allowed maximum length can be set through the max-length parameter in | ||
* bytes (see {@link AbstractStringPrimitiveConverter#init(Mapping, SQLFeatureStore)}). | ||
* </p> | ||
* | ||
* @see <a href="https://www.rfc-editor.org/rfc/rfc4648.txt">The Base16, Base32, and | ||
* Base64 Data Encodings</a> | ||
* @author <a href="mailto:reichhelm@grit.de">Stephan Reichhelm</a> | ||
*/ | ||
public class BinaryBase64PrimitiveConverter extends AbstractStringPrimitiveConverter { | ||
|
||
private static final Logger LOG = getLogger(BinaryBase64PrimitiveConverter.class); | ||
|
||
protected final Base64.Decoder decoder; | ||
|
||
protected final Base64.Encoder encoder; | ||
|
||
protected BinaryBase64PrimitiveConverter(Base64.Encoder enc, Base64.Decoder dec) { | ||
super(Types.BLOB); | ||
this.decoder = dec; | ||
this.encoder = enc; | ||
} | ||
|
||
public BinaryBase64PrimitiveConverter() { | ||
this(Base64.getEncoder(), Base64.getDecoder()); | ||
} | ||
|
||
String formatInput(String value) throws SQLException { | ||
return value; | ||
} | ||
|
||
String formatOutput(String value) throws SQLException { | ||
return value; | ||
} | ||
|
||
@Override | ||
public PrimitiveValue toParticle(ResultSet rs, int colIndex) throws SQLException { | ||
try (InputStream is = rs.getBinaryStream(colIndex)) { | ||
if (is == null) { | ||
return null; | ||
} | ||
byte[] raw = IOUtils.toByteArray(is); | ||
return new PrimitiveValue(formatOutput(encoder.encodeToString(raw)), pt); | ||
} | ||
catch (IOException ioe) { | ||
LOG.trace("Exception", ioe); | ||
throw new SQLException("Conversation from binary to Base64 failed: " + ioe.getMessage()); | ||
} | ||
} | ||
|
||
@Override | ||
public void setParticle(PreparedStatement stmt, PrimitiveValue particle, int paramIndex) throws SQLException { | ||
final String val; | ||
if (particle.getValue() != null) { | ||
val = particle.getValue().toString(); | ||
} | ||
else { | ||
val = null; | ||
} | ||
if (val == null) { | ||
try { | ||
stmt.setNull(paramIndex, sqlType); | ||
} | ||
catch (SQLFeatureNotSupportedException ignored) { | ||
stmt.setString(paramIndex, null); | ||
} | ||
} | ||
else if (val.length() > (((float) maxLen / 3) * 4 * 1.1)) { | ||
// NOTE encoded is 4/3 the size of the not encoded content, but 10 percent is | ||
// added for linebreak etc. | ||
throw new SQLException("Maximum length of " + maxLen + " bytes exceeded in pre check."); | ||
} | ||
else { | ||
byte[] raw = decoder.decode(formatInput(val)); | ||
if (raw.length > maxLen) { | ||
throw new SQLException("Maximum length of " + maxLen + " bytes exceeded."); | ||
} | ||
|
||
stmt.setBinaryStream(paramIndex, new ByteArrayInputStream(raw), raw.length); | ||
} | ||
} | ||
|
||
} |
Oops, something went wrong.