Java - How to use a existing Enum inside class - java

Can someone give me an example how to use this enum. I'm trying to find out what I need to import and how I can use the methods of the following Enum:
http://docs.oracle.com/javaee/6/api/javax/ws/rs/core/Response.Status.html

You would need the correct package containing the enum definition. In this instance javax.ws.rs. Visit this post to know where to find it.
Can't find javax.ws.rs package in jdk
After you have added the .jar to your CLASSPATH you can simple import it
import javax.ws.rs.core.Response.Status;

Here goes one example in JSON:
public Response retrieveSomething(String uuid) {
Entity entity = service.getById(uuid);
if(entity == null) {
return Response.status(Response.Status.NOT_FOUND).entity("Entity not found for UUID: " + uuid).build();
}
String json = //convert entity to json
return Response.ok(json, MediaType.APPLICATION_JSON).build();
}

In many respects an enum is just like z regular class; the answer is practically the for how to use an enum as how to use a class:
Step 1: import the enum to your program:
import javax.ws.rs.core.Response.Status;
Step 2: Het a reference to an instance (unlike regular classes, you can't create an instance - that is done for you by the JVM), either from the enum:
Status status = Status.OK;
or as the returned value of a method:
Status status = response.getStatus();
Step 3: Invoke a method:
int code = status.getStatusCode();

Here is a very simple example using the Status enum:
First import Response:
import javax.ws.rs.core.Response;
Then your code...
public Response create() {
return Response.status(Response.Status.CONFLICT).build();
}

Related

Is this a valid use of the java ClassGraph api?

Using compile 'io.github.classgraph:classgraph:4.8.65'
https://github.com/classgraph/classgraph/wiki/ClassGraph-API
Java 8
ScanResult scanResult =
new ClassGraph().enableAllInfo()
.whitelistPackages("abc1")
.whitelistPackages("abc2")
.whitelistPackages("java")
.scan();
When I encounter ClassInfo objects for classes from the packages abc1 or abc2 they are able to reference things like java.util.HashMap, I see them in the FieldInfo.
But when I then proceed to do scanResult.getClassInfo("java.util.HashMap"), it returns null.
(following FieldInfos for other classes within the abc1 or abc2 packages do return more ClassInfo objects)
My question is, is it correct to think I would be able to get the ClassInfo objects to the java jre classes via the ClassGraph method chaining as shown above?
Added this test which fails, it surprisingly only prints one class rather than expected dozens:
package abc;
import io.github.classgraph.ScanResult;
import io.github.classgraph.ClassGraph;
import io.github.classgraph.ClassInfo;
import java.util.*;
import java.io.*;
import java.util.function.*;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
#SpringJUnitConfig
#SpringBootTest(classes = {})
public class ExamplesSpec {
#org.junit.jupiter.api.Test
#org.junit.jupiter.api.DisplayName(value="test_for_built_in_java_jre_classes")
public void test_on_line_42() throws Exception {
System.out.println("test_for_built_in_java_jre_classes");
ClassInfo found = null;
try (
ScanResult result = new ClassGraph().enableAllInfo().whitelistPackages("java.util").scan()
) {
System.out.println("here all the classes....");
for( ClassInfo item : result.getAllClasses()) {
System.out.println("here classinfo: " + item);
}
found = result.getClassInfo("java.util.HashMap");
}
assert found != null;
}
}
The only class found is this:
here classinfo: public class java.util.zip.VFSZipFile implements java.util.zip.ZipConstants
Found the answer!
In the setup of the ClassGraph, in order to scan the jre provided classes, you would need to add this to the method chaining:
.enableSystemJarsAndModules()
For example:
new ClassGraph().enableAllInfo()
.whitelistPackages("abc1")
.whitelistPackages("abc2")
.whitelistPackages("java")
.enableSystemJarsAndModules()
.scan();
This is detailed in the documentation found here:
https://github.com/classgraph/classgraph/wiki/API:-ClassGraph-Constructor#configuring-the-classgraph-instance

How to Load an Entity Inside a Spring Data REST Server by Self Link?

Given a Spring Data REST (SDR) server built with Spring Boot Gradle Plugin 2.2.5.RELEASE, is it possible to load an #Entity by self link within the server application?
I'm aware how to access it with an HTTP client, e.g. using curl:
$ curl localhost/users/1 # Responds with 200 OK and JSON representation
What I'm searching for is a mechanism to do this in the server using Java only, ideally using a standard SDR mechanism:
#Service
public class SelfLinkResolver {
public Object findBySelfLink(Link self) {
if (self == null || !self.getRel().equals(SELF)) {
throw new IllegalArgumentException("Non-null self link expected");
}
return null; // How to return the entity using a standard SDR mechanism?
}
public void exampleCall() {
Link self = new Link("localhost/users/1");
Object entity = findBySelfLink(self);
requireNonNull(entity, "Failed to load entity by self link");
}
}
An internal solution is parse your link and extract the ID (1 in your example), the call repository.findById(id).
Another solution would be new a RestTemplate, call your own API.
I finally came up with this solution, which uses SDR's UriToEntityConverter. In contrast to my question, it requires not only the self link, but also the entity class. It therefore doesn't fully answer my initial question.
I guess that there is no SDR solution that does not require the entity class, since there is no need for this within the framework, at least for usual API calls. SDR is always provided with the type information through the Repository, to which the self link refers. However, I didn't dive into other classes such as PersistentEntities, RepositoryInvokerFactory or Repositories, which might provide a solution for this.
WARNING: My tested implementation differs from this. This code is untested, but should illustrate the idea.
import lombok.NonNull;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.data.mapping.context.PersistentEntities;
import org.springframework.data.repository.support.Repositories;
import org.springframework.data.repository.support.RepositoryInvokerFactory;
import org.springframework.data.rest.core.UriToEntityConverter;
import org.springframework.hateoas.Link;
import org.springframework.stereotype.Component;
import java.net.URI;
import java.util.Optional;
import static com.google.common.base.Preconditions.checkArgument;
import static java.lang.String.format;
import static org.springframework.hateoas.IanaLinkRelations.SELF;
#Component
public class SelfLinkToEntityConverter extends UriToEntityConverter {
private static final TypeDescriptor URI_DESCRIPTOR = TypeDescriptor.valueOf(URI.class);
SelfLinkToEntityConverter(#NonNull PersistentEntities entities,
#NonNull RepositoryInvokerFactory invokerFactory,
#NonNull Repositories repositories) {
super(entities, invokerFactory, repositories);
}
#NonNull
public <T> Optional<T> findBySelfLink(#NonNull Link self, #NonNull Class<T> entityClass) {
checkArgument(self.getRel().equals(SELF), "Non-null self link expected");
URI uri = self.expand().toUri();
TypeDescriptor typeDescriptor = TypeDescriptor.valueOf(entityClass);
try {
#SuppressWarnings("unchecked")
T entity = (T) super.convert(uri, URI_DESCRIPTOR, typeDescriptor);
return Optional.ofNullable(entity);
} catch (IllegalArgumentException o_O) {
throw new IllegalArgumentException(format("Failed to load %s: %s",
entityClass.getSimpleName(), self.getHref()));
}
}
}

How would I write an automated check that every parameter has a specific annotation?

I'm writing a Rest API and my automated tests are calling the class directly without deploying the to the server. As an example, I am testing this method:
#GET
#Path("/{referenceId}")
#Produces("application/json")
public String findByReferenceId(#PathParam("referenceId") String referenceId,
String view) {
My tests are checking that the logic works and they pass. But this code has a bug: I forgot to put a #QueryParam annotation on that view parameter. So this code works when tested, but if you try to use this resource on the deployed app, the view parameter will never be settable.
There are many ways I can solve this, but my current preference is to somehow write an automated check that if a method has a #Path annotation, then every parameter must have either a #PathParam, a #QueryParam or whatever other valid annotation can be there.
I prefer this over a new end-to-end test, because my other tests are already covering 95% of that logic. I just don't know how to automate this check. I'm using Maven and CXF (which means I'm using Spring). I'm hoping there's a plugin that can be configured to do this.
Something I just realized: It's valid to have a single parameter without an annotation. When you do this, jax-rs sets it to the entity you pass in. I'm not sure how to deal with this scenario. I could create my own custom annotation called #Payload and tell people to use it, but something seems wrong about that.
Here's my solution. In the end, I decided to create a #RawPayload annotation. Otherwise, I can't know if the missing annotation is intentional or not. Here's where I got the Reflections class: https://code.google.com/p/reflections/
import org.junit.Test;
import org.reflections.Reflections;
import org.reflections.scanners.MethodAnnotationsScanner;
import javax.ws.rs.Path;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Set;
import static org.junit.Assert.assertTrue;
...
#Test
public void testAllParametersAreAnnotated() throws Exception {
String message = "You are missing a jax-rs annotation on a method's parameter: ";
Reflections reflections = new Reflections("package.for.my.services", new MethodAnnotationsScanner());
Set<Method> resourceMethods = reflections.getMethodsAnnotatedWith(Path.class);
assertTrue(resourceMethods.size() > 0);
for (Method resourceMethod : resourceMethods) {
for (int i = 0; i < resourceMethod.getGenericParameterTypes().length; i++) {
Annotation[] annotations = resourceMethod.getParameterAnnotations()[i];
boolean annotationExists = annotations.length > 0;
assertTrue(message +
resourceMethod.getDeclaringClass().getCanonicalName() +
"#" +
resourceMethod.getName(),
annotationExists && containsJaxRsAnnotation(annotations));
}
}
}
private boolean containsJaxRsAnnotation(Annotation[] annotations) {
for (Annotation annotation : annotations) {
if (annotation instanceof RawPayload) {
return true;
}
if (annotation.annotationType().getCanonicalName().startsWith("javax.ws.rs")) {
return true;
}
}
return false;
}
Here's my annotation:
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* I'm creating this marker so that we can put it on raw payload params. This is normally unnecessary,
* but it lets me write a very useful automated test.
*/
#Retention(RetentionPolicy.RUNTIME)
public #interface RawPayload {
}

How to test java code that uses Basho's riak-java-client?

I'm creating a small java service that returns a list of restaurants depending on the selected place.
Data is retrieved from Riak using com.basho.riak:riak-client:2.0.0 and the read operation is wrapped in a TenacityCommand.
Important classes are described below and I would be happy if you could assist me in creating a solid and simple unit test.
Commands are created using a factory:
package service.command.factory;
import com.basho.riak.client.api.RiakClient;
import com.basho.riak.client.api.commands.kv.FetchValue;
import com.basho.riak.client.core.query.Location;
import com.basho.riak.client.core.query.Namespace;
import domain.Place;
import service.command.FetchRestaurantsCommand;
public class FetchRestaurantsCommandFactory {
private final RiakClient riakClient;
private final Namespace namespace;
public FetchRestaurantsCommandFactory(final RiakClient riakClient, final Namespace namespace) {
this.riakClient = riakClient;
this.namespace = namespace;
}
public FetchRestaurantsCommand create(final Place place) {
Location location = new Location(namespace, place.getName());
FetchValue riakCommand = new FetchValue.Builder(location).build();
return new FetchRestaurantsCommand(riakClient, riakCommand);
}
}
And the command looks like this:
package service.command;
import java.util.Optional;
import service.command.keys.WhereToEatDependencyKeys;
import com.basho.riak.client.api.RiakClient;
import com.basho.riak.client.api.commands.kv.FetchValue;
import com.basho.riak.client.api.commands.kv.FetchValue.Response;
import com.yammer.tenacity.core.TenacityCommand;
import domain.Restaurant;
import domain.RestaurantList;
public class FetchRestaurantsCommand extends TenacityCommand<Optional<RestaurantList>>{
private final RiakClient riakClient;
private final FetchValue fetchValue;
public FetchRestaurantsCommand(RiakClient riakClient, FetchValue fetchValue) {
super(WhereToEatDependencyKeys.RIAK_GET_RESTAURANTS);
this.fetchValue = fetchValue;
this.riakClient = riakClient;
}
#Override
protected Optional<RestaurantList> run() throws Exception {
Response response = riakClient.execute(fetchValue);
return Optional.ofNullable(response.getValue(RestaurantList.class));
}
#Override
protected Optional<RestaurantList> getFallback() {
return Optional.of(RestaurantList.createFallback(new Restaurant("My failure suggestion")));
}
}
The above classes are used like:
Place place = // Created from url parameter
RiakClient riakClient = // created on start using the app's conf
Namespace namespace = // created on start using the app's conf
FetchRestaurantsCommandFactory factory = new FetchRestaurantsCommandFactory(riakClient, namespace);
FetchRestaurantsCommand command = factory.create(place);
return command.execute();
Apart from the features provided by TenacityCommand, how should I assert that my system fetches data as expeceted?
My initial idea was to mock a RiakClient to return a predefined FetchValue.Response and then make assertions on the resulting RestaurantList.
Unfortunately its not possible to instantiate or Mockito.mock a FetchValue.Response due to its design.
The accepted answer in How to mock riak java client? describes why Mockito won't work.
As far a I understood you want to write unit test. So you want to test that assuming some Response whether Optional<RestaurantList> instance is constructed correctly or not.
What I can think of is to wrap riakClient.execute(fetchValue); in a protected (or package private) helper function like:
Response fetch() {
return riakClient.execute(fetchValue);
}
Then in your test you can inherit from FetchRestaurantsCommand and override fetch function by returning any Response
Now, you can write any test to see whether the conversion of given Response to Optional<RestaurantList> behaves as expected or not.
If you need entire code and my explanation is not clear enough let me know to provide it.
I ended up using PowerMock as suggested by #gontard. See my unit test on GitHub: FetchRestaurantsCommandTest.java
I considered to create a fake/mock RiakClient in the com.basho.riak.client package. Such class could hopefully instantiate the Response object in the same way as the real client does. It would probably work for fetchValue but it would grow too big when involving more advanced Riak concepts s.a. siblings.

How can I prevent Eclipse from supplying deprecated classes when importing?

I have a recurring problem using Eclipse. Consider the following example:
As you can see I've pressed Ctrl+Shift+O. I can choose from a deprecated and a non-deprecated annotation. My problem is that I am often supplied with dozens of classes and half of them are deprecated (a perfect example is the JUnit Assert classes).
My question is how can I make Eclipse ignore all deprecated classes when organizing imports?
Currently Eclipse does not provide such an option... Eclipse Documentation for Organise Imports (Kepler version).
However, with a fudge you can achieve the same result...
Eclipse allows you to provide a list of classes/packages to filter-out.
To do this, navigate to Preferences > Type Filters.
I've done this in my environment to ensure "java.awt.List" is not suggested when I really want "java.util.List".
What you want is to add all deprecated classes to this list.
This list is maintained in your eclipse workspace preferences...
File ... C:\Users\[YOUR_USER_NAME]\workspace\.metadata\.plugins\org.eclipse.core.runtime\.settings\org.eclipse.jdt.ui.prefs
Property ... org.eclipse.jdt.ui.typefilter.enabled=java.awt.List;
All that is required is that you create a list of deprecated classes, and store it in this properties file.
Eclispe can help create this list...
Perform a "Java Search" for "Deprecated".
Then group the results by type.
And copy the results using "Copy Qualified Name"
The results will contain Generics, and this should be removed.
For example, "javafx.scene.control.Cell<T>" should read "javafx.scene.control.Cell".
In addition to containing deprecated classes, the results will also contain any class that has the word "Deprecated". This could be a comment or a method annotation. This list will need to be filtered to retain only deprecated classes.
The script below processes this class list to remove generics, and filtering out classes that are not deprecated (ie, only has method deprecation). The class list is read from a file named "DeprecatedClassList.txt". When it cannot check the class annotation, it skips the class and prints it out (for manual checking).
import java.lang.annotation.Annotation;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class ConfigurationGenerator {
public static void main(String[] args) throws Exception {
List<String> cleanedList = Files
.readAllLines(Paths.get("DeprecatedClassList.txt")).stream()
.map(ConfigurationGenerator::removeGenerics)
.filter(ConfigurationGenerator::hasDeprecatedConstructor)
.collect(Collectors.toList());
String propertyName = "org.eclipse.jdt.ui.typefilter.enabled=";
String propertyValue = String.join(";", cleanedList).concat(";");
String configuration = propertyName + propertyValue;
System.out.println("Configuration property...");
System.out.println(configuration);
}
public static String removeGenerics(String className) {
int openingBracket = className.indexOf("<");
if (openingBracket == -1)
return className;
else
return className.substring(0, openingBracket);
}
public static boolean hasDeprecatedConstructor(String className) {
Class theClass = null;
try {
theClass = Class.forName(className);
} catch (Throwable e) {
// Ignore bad results
System.out.println("Skipping: " + className);
return false;
}
Annotation[] annotations = theClass.getAnnotations();
Optional<Annotation> deprecatedConstructor = Stream
.of(annotations)
.filter(annotation -> annotation.toString().equals(
"#java.lang.Deprecated()")).findAny();
return deprecatedConstructor.isPresent();
}
}
There is one problem with this approach though. You may want to use a deprecated class when a non-deprecated version does not exist. You will not see the deprecated class if it has been purposefully hidden. To resolve that, just be sure you exclude them from the filter.

Categories

Resources