+ * {@code # Use default locale + * curl -X GET+ * + * @author Tobias Erdle + */ +@javax.annotation.Priority(1) +@javax.enterprise.context.ApplicationScoped +public class QueryParamLocaleResolver implements javax.mvc.locale.LocaleResolver { + @javax.inject.Inject + java.util.logging.Logger log; + + @java.lang.Override + public java.util.Locale resolveLocale(final javax.mvc.locale.LocaleResolverContext context) { + final java.lang.String queryLang = context.getUriInfo().getQueryParameters().getFirst("lang"); + log.log(java.util.logging.Level.INFO, "QueryParamLocaleResolver::resolveLocale:lang:{0}", queryLang); + return queryLang != null ? java.util.Locale.forLanguageTag(queryLang) : null; + } +}; + ``` + ++ * + * # Set german locale by query param + * curl -X GET ?lang=de-DE} + *
+ * {@code # Use default locale + * curl -X GET+ * + * @author Tobias Erdle + */ +@javax.annotation.Priority(1) +@javax.enterprise.context.ApplicationScoped +public class QueryParamLocaleResolver implements javax.mvc.locale.LocaleResolver { + @javax.inject.Inject + java.util.logging.Logger log; + + @java.lang.Override + public java.util.Locale resolveLocale(final javax.mvc.locale.LocaleResolverContext context) { + final java.lang.String queryLang = context.getUriInfo().getQueryParameters().getFirst("lang"); + log.log(java.util.logging.Level.INFO, "QueryParamLocaleResolver::resolveLocale:lang:{0}", queryLang); + return queryLang != null ? java.util.Locale.forLanguageTag(queryLang) : null; + } +}; + ``` + ++ * + * # Set german locale by query param + * curl -X GET ?lang=de-DE} + *
memoryOutputStream
or
+ * diskOutputStream
.
+ */
+ private java.io.OutputStream currentOutputStream;
+
+ /**
+ * The file to which output will be directed if the threshold is exceeded.
+ */
+ private java.io.File outputFile = null;
+
+ /**
+ * The temporary file prefix.
+ */
+ private final java.lang.String prefix;
+
+ /**
+ * The temporary file suffix.
+ */
+ private final java.lang.String suffix;
+
+ /**
+ * The directory to use for temporary files.
+ */
+ private final java.io.File directory;
+
+ /**
+ * True when close() has been called successfully.
+ */
+ private boolean closed = false;
+
+ // ----------------------------------------------------------- Constructors
+ /**
+ * Constructs an instance of this class which will trigger an event at the
+ * specified threshold, and save data to a temporary file beyond that point.
+ *
+ * @param threshold
+ * The number of bytes at which to trigger an event.
+ * @param prefix
+ * Prefix to use for the temporary file.
+ * @param suffix
+ * Suffix to use for the temporary file.
+ * @param directory
+ * Temporary file directory.
+ * @since 1.4
+ */
+ public OffloadingOutputStream(int threshold, java.lang.String prefix, java.lang.String suffix, java.io.File directory) {
+ this(threshold, null, prefix, suffix, directory);
+ if (prefix == null) {
+ throw new java.lang.IllegalArgumentException("Temporary file prefix is missing");
+ }
+ }
+
+ /**
+ * Constructs an instance of this class which will trigger an event at the
+ * specified threshold, and save data either to a file beyond that point.
+ *
+ * @param threshold
+ * The number of bytes at which to trigger an event.
+ * @param outputFile
+ * The file to which data is saved beyond the threshold.
+ * @param prefix
+ * Prefix to use for the temporary file.
+ * @param suffix
+ * Suffix to use for the temporary file.
+ * @param directory
+ * Temporary file directory.
+ */
+ private OffloadingOutputStream(int threshold, java.io.File outputFile, java.lang.String prefix, java.lang.String suffix, java.io.File directory) {
+ super(threshold);
+ this.outputFile = outputFile;
+ memoryOutputStream = new org.codehaus.plexus.archiver.zip.ByteArrayOutputStream(threshold / 10);
+ currentOutputStream = memoryOutputStream;
+ this.prefix = prefix;
+ this.suffix = suffix;
+ this.directory = directory;
+ }
+
+ // --------------------------------------- ThresholdingOutputStream methods
+ /**
+ * Returns the current output stream. This may be memory based or disk
+ * based, depending on the current state with respect to the threshold.
+ *
+ * @return The underlying output stream.
+ * @exception java.io.IOException
+ * if an error occurs.
+ */
+ @java.lang.Override
+ protected java.io.OutputStream getStream() throws java.io.IOException {
+ return currentOutputStream;
+ }
+
+ /**
+ * Switches the underlying output stream from a memory based stream to one
+ * that is backed by disk. This is the point at which we realise that too
+ * much data is being written to keep in memory, so we elect to switch to
+ * disk-based storage.
+ *
+ * @exception java.io.IOException
+ * if an error occurs.
+ */
+ @java.lang.Override
+ protected void thresholdReached() throws java.io.IOException {
+ if (prefix != null) {
+ outputFile = java.io.File.createTempFile(prefix, suffix, directory);
+ }
+ currentOutputStream = java.nio.file.Files.newOutputStream(outputFile.toPath());
+ }
+
+ public java.io.InputStream getInputStream() throws java.io.IOException {
+ java.io.InputStream memoryAsInput = memoryOutputStream.toInputStream();
+ if (outputFile == null) {
+ return memoryAsInput;
+ }
+ return new java.io.SequenceInputStream(memoryAsInput, java.nio.file.Files.newInputStream(outputFile.toPath()));
+ }
+
+ // --------------------------------------------------------- Public methods
+ /**
+ * Returns the data for this output stream as an array of bytes, assuming
+ * that the data has been retained in memory. If the data was written to
+ * disk, this method returns null
.
+ *
+ * @return The data for this output stream, or null
if no such
+ data is available.
+ */
+ public byte[] getData() {
+ if (memoryOutputStream != null) {
+ return memoryOutputStream.toByteArray();
+ }
+ return null;
+ }
+
+ /**
+ * Returns either the output file specified in the constructor or
+ * the temporary file created or null.
+ * + * If the constructor specifying the file is used then it returns that + * same output file, even when threshold has not been reached. + *
+ * If constructor specifying a temporary file prefix/suffix is used
+ * then the temporary file created once the threshold is reached is returned
+ * If the threshold was not reached then null
is returned.
+ *
+ * @return The file for this output stream, or null
if no such
+ file exists.
+ */
+ public java.io.File getFile() {
+ return outputFile;
+ }
+
+ /**
+ * Closes underlying output stream, and mark this as closed
+ *
+ * @exception java.io.IOException
+ * if an error occurs.
+ */
+ @java.lang.Override
+ public void close() throws java.io.IOException {
+ super.close();
+ closed = true;
+ currentOutputStream.close();
+ }
+};
+ ```
+
+
+ * The metric is defined as follows: Given two points A and B, representing + * circles centered at (x1, y1) and (x2, y2) with radii r1 and r2 respectively, + * the distance is calculated as sqrt((x1 - x2)^2 + (y1 - y2)^2) + |r1 - r2|. + *
+ * This metric can be used to find the nearest circle to a given center (x, y) + * in a proximity search. To perform the search, use a point (x, y, R) where R + * is greater than or equal to the maximum radius of a circle in the proximity + * structure. + * + * @param p1 + * 3D point representing the first circle (x1, y1, r1) + * @param p2 + * 3D point representing the second circle (x2, y2, r2) + * @return the distance between the two points based on the custom metric + */ +private static final org.tinspin.index.PointDistanceFunction circleDistanceMetric = (p1, p2) -> { + // from https://stackoverflow.com/a/21975136/ + final double dx = p1[0] - p2[0]; + final double dy = p1[1] - p2[1]; + final double dz = p1[2] - p2[2]; + double euclideanDistance = java.lang.Math.sqrt((dx * dx) + (dy * dy)); + double absZDifference = java.lang.Math.abs(dz); + return euclideanDistance + absZDifference;// negative if inside + +};; ```