I have gone thru the documentation of Firestore: https://firebase.google.com/docs/firestore/query-data/listen?authuser=0
But while using same code, i am not able to resolve symbols such as DocumentChange, EventListener.
Similarly, I am not able to resolve methods such as getDocumentChanges, getDocument, addSnapshotListener.
I have already imported 'com.google.firebase:firebase-admin:5.8.0'.
build.gradle file
group 'firestore'
version '1.0-SNAPSHOT'
apply plugin: 'java'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
}
dependencies {
compile 'com.google.firebase:firebase-admin:5.8.0'
}
Here is the code, I am trying:
package firestore;
import com.google.api.core.SettableApiFuture;
import com.google.firestore.v1beta1.DocumentChange;
import com.google.cloud.firestore.DocumentChange;
import com.google.cloud.firestore.DocumentChange.Type;
import com.google.cloud.firestore.EventListener;
import com.google.cloud.firestore.ListenerRegistration;
import com.google.cloud.firestore.Firestore;
import com.google.cloud.firestore.FirestoreException;
import com.google.cloud.firestore.Query;
import com.google.cloud.firestore.QuerySnapshot;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import javax.annotation.Nullable;
import static com.google.api.ChangeType.ADDED;
import static com.google.api.ChangeType.MODIFIED;
import static com.google.api.ChangeType.REMOVED;
/**
* Snippets to demonstrate Firestore 'listen' operations.
*/
#SuppressWarnings("Convert2Lambda")
public class FirestoreChange {
private static final long TIMEOUT_SECONDS = 5;
private final Firestore db;
FirestoreChange(Firestore db) {
this.db = db;
}
/**
* Listen to a query, returning the list of DocumentChange events in the first snapshot.
*/
List<DocumentChange> listenForChanges() throws Exception {
SettableApiFuture<List<DocumentChange>> future = SettableApiFuture.create();
// [START listen_for_changes]
db.collection("cities")
.whereEqualTo("state", "CA")
.addSnapshotListener(new EventListener<QuerySnapshot>() {
#Override
public void onEvent(#Nullable QuerySnapshot snapshots,
#Nullable FirestoreException e) {
if (e != null) {
System.err.println("Listen failed: " + e);
return;
}
for (DocumentChange dc : snapshots.getDocumentChanges()) {
switch (dc.getType()) {
case ADDED:
System.out.println("New city: " + dc.getDocument().getData());
break;
case MODIFIED:
System.out.println("Modified city: " + dc.getDocument().getData());
break;
case REMOVED:
System.out.println("Removed city: " + dc.getDocument().getData());
break;
default:
break;
}
}
// [START_EXCLUDE silent]
if (!future.isDone()) {
future.set(snapshots.getDocumentChanges());
}
// [END_EXCLUDE]
}
});
// [END listen_for_changes]
return future.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
}
}
This is happening because you didn't add Cloud Firestore dependencies in build.gradle file at all. Adding firebase-admin is not enought to make Firestore work. So to solve this, just add this line of code:
compile 'com.google.firebase:firebase-firestore:11.8.0'
Right after the firebase-admin dependencies. Sync your project and try again.
Related
I have a Spring Boot App with the following classes in the src/main/java/in/javacoder/overlayapp package
build.gradle
plugins {
id 'java'
id 'org.springframework.boot' version '3.0.2'
id 'io.spring.dependency-management' version '1.1.0'
id 'application'
id 'org.openjfx.javafxplugin' version '0.0.13'
}
javafx {
version = "17"
modules = [ 'javafx.controls' ]
}
group = 'in.techpro424'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
tasks.named('test') {
useJUnitPlatform()
}
CoordinateOverlayAppApplication.java
package in.techpro424.coordinateoverlayapp;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class CoordinateOverlayAppApplication {
public static void main(String[] args) {
SpringApplication.run(CoordinateOverlayAppApplication.class, args);
}
}
CoordinateRestController.java
package in.techpro424.coordinateoverlayapp;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
#RestController
public class CoordinateRestController {
public static double xCoord;
public static double yCoord;
public static double zCoord;
#PostMapping(value = "/coordinateOverlay")
public int receiveCoordinates(#RequestParam(name = "xCoordinate") Double xCoordinate, #RequestParam(name = "yCoordinate") Double yCoordinate, #RequestParam(name = "zCoordinate") Double zCoordinate) {
CoordinateRestController.xCoord = xCoordinate;
System.out.println(CoordinateRestController.xCoord);
CoordinateRestController.yCoord = yCoordinate;
System.out.println(CoordinateRestController.yCoord);
CoordinateRestController.zCoord = zCoordinate;
System.out.println(CoordinateRestController.zCoord);
javafx.application.Application.launch(RenderCoordinateOverlay.class);
return 1;
}
}
RenderCoordinateOverlay.java
package in.techpro424.coordinateoverlayapp;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
public class RenderCoordinateOverlay extends Application {
double radius = 50;
#Override
public void start(Stage primaryStage) {
Group root = new Group();
Text coordinates = new Text();
coordinates.setText("X:" + CoordinateRestController.xCoord + ", Y:" + CoordinateRestController.yCoord + ", Z:" + CoordinateRestController.zCoord);
root.getChildren().add(coordinates);
Scene scene = new Scene(root, Color.TRANSPARENT);
scene.getRoot().setStyle("-fx-background-color: transparent");
primaryStage.initStyle(StageStyle.TRANSPARENT);
primaryStage.setScene(scene);
primaryStage.show();
primaryStage.setAlwaysOnTop(true);
}
public static void main(String[] args) {
launch(args);
}
}
I want to render this overlay on the screen whenever I receive the POST request with the specified params
I tried using javafx.application.Application.launch(RenderCoordinateOverlay.class); in the receiveCoordinates() function
I expected the overlay to render the text the moment I sent the POST request
However, when I sent the POST request, only a completely transparent window was rendered with this error in the console:
2023-01-27T15:01:27.384+05:30 WARN 13060 --- [JavaFX-Launcher] javafx: Unsupported JavaFX configuration: classes were loaded from 'unnamed module #1ec4c0e8'
The SpringBoot application is running on my PC with a display and I expect the UI to be displayed on the PC.
I use Postman to send the post.
I am trying to build a jar with the following build.gradle:
plugins {
id 'application'
id 'org.openjfx.javafxplugin' version '0.0.10'
}
application {
mainClass.set("edu.hm.dako.auditLogServer.AdminGuiStarter")
}
jar.enabled = true
javafx {
version = "18"
modules = ['javafx.controls', 'javafx.fxml']
}
sourceSets {
main {
resources {
srcDirs = ["src/main/java"]
includes = ["**/*.fxml"]
}
}
}
dependencies {
implementation project(':common')
implementation project(':communication')
implementation 'org.openjfx:javafx:18'
implementation group: 'org.apache.commons', name: 'commons-configuration2', version: '2.8.0'
implementation group: 'commons-beanutils', name: 'commons-beanutils', version: '1.9.4'
}
repositories {
mavenCentral()
}
jar {
manifest {
attributes "Main-Class": "edu.hm.dako.auditLogServer.AdminGuiStarter"
}
archiveBaseName = 'AdminGradle'
archiveVersion = '0.1.0'
}
The Main class of the project is following:
package edu.hm.dako.auditLogServer;
import java.io.IOException;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class AdminGuiStarter extends Application{
#Override
public void start(Stage stage) {
try {
Parent root = FXMLLoader.load(getClass().getResource("AdminGui.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
} catch (IOException e) {
e.printStackTrace();
System.out.println(e);
}
}
// bitte über gradle starten, da sonst JavaFx Runtime components fehlen
public static void main(String[] args) {
launch();
}
}
When I then try to execute the jar, I get this error: java.lang.NoClassDefFoundError: javafx/application/Application
How can I fix this so that the jar will execute successful? When I run the Application via Gradle run, everything works fine.
I get an error in he "import org.springframework.data cannot be
resolved" in following code
package com.steinko.reactsprinboottutorial.RestfulWebService;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
#Repository
public interface TodoRepository extends CrudRepository<Todo, Long>{
List<Todo> findByName(String Name);
}
The gradle build.gradle looks like
plugins {
id 'org.springframework.boot' version '2.3.3.RELEASE'
id 'io.spring.dependency-management' version '1.0.10.RELEASE'
}
apply plugin: 'java'
apply plugin: 'eclipse'
repositories {
mavenCentral()
jcenter()
mavenLocal()
// maven { url "http://dl.bintray.com/epam/reportportal" }
}
sourceCompatibility = '14'
sourceSets {
intTest {
compileClasspath += sourceSets.main.output
runtimeClasspath += sourceSets.main.output
}
}
configurations {
intTestImplementation.extendsFrom implementation
intTestCompile.extendsFrom testCompile
intTestRuntimeOnly.extendsFrom runtimeOnly
}
dependencies {
//implementation 'com.epam.reportportal:logger-java-log4j:5.0.2'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.modelmapper:modelmapper:2.3.8'
// https://mvnrepository.com/artifact/javax.validation/validation-api
compile group: 'javax.validation', name: 'validation-api', version: '2.0.1.Final'
implementation 'org.springframework.boot:spring-boot-starter-validation'
runtimeOnly 'org.postgresql:postgresql'
// https://mvnrepository.com/artifact/org.testcontainers/testcontainers
testCompile group: 'org.testcontainers', name: 'testcontainers', version: '1.15.0-rc1'
testCompile group: 'org.testcontainers', name: 'postgresql', version: '1.15.0-rc1'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'io.rest-assured:spring-mock-mvc:4.3.1'
testImplementation 'io.rest-assured:rest-assured-common:4.3.1'
testImplementation 'org.springframework.boot:spring-boot-starter-data-jpa'
testCompile group: 'org.modelmapper', name: 'modelmapper', version: '2.3.8'
testImplementation 'com.epam.reportportal:agent-java-junit5:5.0.0-RC-1'
intTestCompile group: 'org.testcontainers', name: 'testcontainers', version: '1.15.0-rc1'
intTestCompile group: 'org.testcontainers', name: 'postgresql', version: '1.15.0-rc1'
intTestImplementation 'org.springframework.boot:spring-boot-starter-test'
intTestImplementation 'io.rest-assured:spring-mock-mvc:4.1.2'
intTestImplementation 'com.epam.reportportal:agent-java-junit5:5.0.0-RC-1'
intTestRuntimeOnly 'org.postgresql:postgresql'
}
test {
// testLogging.showStandardStreams = true
useJUnitPlatform()
// systemProperty 'junit.jupiter.extensions.autodetection.enabled', true
}
task integrationTest(type: Test) {
description = 'Runs integration tests.'
group = 'verification'
testClassesDirs = sourceSets.intTest.output.classesDirs
classpath = sourceSets.intTest.runtimeClasspath
shouldRunAfter test
}
When I run the test for the service I get a nullpointer for repository
TodoServiceTest > shoulCreateTodo() FAILED
java.lang.NullPointerException at TodoServiceTest.java:55
TodoServiceTest > shouldDeleteTodo() FAILED
java.lang.NullPointerException at TodoServiceTest.java:48
package com.steinko.reactsprinboottutorial.RestfulWebService;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Disabled;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.Matchers.hasProperty;
import static org.hamcrest.collection.IsIterableContainingInAnyOrder.containsInAnyOrder;
import static org.hamcrest.MatcherAssert.assertThat;
import java.util.Date;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
public class TodoServiceTest {
private static final Logger logger = LoggerFactory.getLogger(TodoServiceTest.class);
private TodoService service = new TodoService();
#Test
void ShouldExist() {
assertNotNull (service);
}
#Test
void shouldDeleteTodo() {
service.deleteTodo("stein", 1L);
}
#Test
void shoulCreateTodo() {
Date date = DateFactory.generetDate("01-01-2020 12:00:00");
TodoDto todo = new TodoDto(1,"Stein","Fix Kjakk", date,false);
service.createTodo(todo);
}
}
The service test looks like
package com.steinko.reactsprinboottutorial.RestfulWebService;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.Validation;
import javax.validation.Validator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
#Service
public class TodoService {
private static final Logger logger = LoggerFactory.getLogger(TodoService.class);
#Autowired
private TodoRepository repository;
public List<TodoDto> getTodos(String name) {
List<Todo> todos = repository.findByName(name);
TodoConverter converter = new TodoConverter();
List<TodoDto> dtos = converter.convertToDtos(todos);
return dtos;
}
public void deleteTodo(String name, Long id) {
repository.deleteById(id);
}
public void createTodo(TodoDto dto) {
TodoConverter converter = new TodoConverter();
Todo todo = converter.convertToEntity(dto);
validateEntity(todo);
repository.save(todo);
}
private void validateEntity(Todo todo) {
List<String> errorMessage = new ArrayList<>();
Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
Set<ConstraintViolation<Todo>> constraintViolations = validator.validate(todo);
for (ConstraintViolation<Todo> constraintViolation : constraintViolations) {
errorMessage.add(constraintViolation.getMessage());
}
if (errorMessage.size() > 0) {
throw new ConstraintViolationException(constraintViolations);
}
}
}
How do I get access to org.springframework.data and an object at repository variabel ?
You have to annotate the test class with either #SpringBootTest or #DataJpaTest so the repository will be initialised and injected into your service. Furthermore, you have to autowire your service in the test, or the repository will not be injected in the instance created by you.
I start learning Spring and in the tutorial from which I learn the lecturer uses the method: startAndAwait, which was in the reactor.ipc.netty.http.server.HttpServer package. Now there is no method, and the package is reactor.netty.http.server.HttpServer.
I would like to learn a solution based on the latest package, therefore my question is what will be the current equivalent of the following code:
import org.springframework.http.server.reactive.HttpHandler;
import org.springframework.http.server.reactive.ReactorHttpHandlerAdapter;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.RouterFunctions;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.ipc.netty.http.server.HttpServer;
import static org.springframework.web.reactive.function.BodyInserters.fromObject;
import static org.springframework.web.reactive.function.server.RequestPredicates.GET;
import static org.springframework.web.reactive.function.server.RouterFunctions.route;
public class HelloServerApplication {
public static void main(String[] args)
{
RouterFunction route = route( GET("/"),
request -> ServerResponse.ok().body(fromObject("Hello")));
HttpHandler httpHandler = RouterFunctions.toHttpHandler(route);
HttpServer server = HttpServer.create("localhost",8080);
server.startAndAwait(new ReactorHttpHandler(httpHandler));
}
}
I was looking for a solution, but my knowledge is so low that I can not cope alone with this problem. So far I wrote I changed the code to the place "server.startAndAwait" still can not replace this method:
package pl.javasurvival.helloServer;
import org.springframework.http.server.reactive.HttpHandler;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.RouterFunctions;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.netty.http.server.HttpServer;
import static org.springframework.web.reactive.function.BodyInserters.fromObject;
import static org.springframework.web.reactive.function.server.RequestPredicates.GET;
import static org.springframework.web.reactive.function.server.RouterFunctions.route;
public class HelloServerApplication {
public static void main(String[] args)
{
RouterFunction route = route( GET("/"),
request -> ServerResponse.ok().body(fromObject("Hello")));
HttpHandler httpHandler = RouterFunctions.toHttpHandler(route);
HttpServer server = HttpServer
.create()
.host("localhost")
.port(8080);
//what is a new method which is equals to startAndAwait
}
}
PS: I forgot to add that I use gradle. This is the build.gradle file:
plugins {
id 'org.springframework.boot' version '2.2.0.M4'
id 'java'
}
apply plugin: 'io.spring.dependency-management'
group = 'pl.javasurvival'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'
repositories {
mavenCentral()
maven { url 'https://repo.spring.io/snapshot' }
maven { url 'https://repo.spring.io/milestone' }
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-webflux:2.2.0.M4'
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
exclude group: 'junit', module: 'junit'
}
testImplementation 'io.projectreactor:reactor-test'
}
test {
useJUnitPlatform()
}
it has been a while, but I've found this question 1 hour ago and now I have solution, so it could be helpful for others.
Without importing old version of reactor.netty, you could try this (scanner is added only for waiting for action)
import org.springframework.http.server.reactive.ReactorHttpHandlerAdapter;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.RouterFunctions;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.netty.http.server.HttpServer;
import java.util.Scanner;
import static org.springframework.web.reactive.function.BodyInserters.fromObject;
import static org.springframework.web.reactive.function.server.RequestPredicates.GET;
import static org.springframework.web.reactive.function.server.RouterFunctions.route;
public class HelloServerApplication {
public static void main(String[] args) {
RouterFunction route = route(GET("/"),
request -> ServerResponse.ok().body(fromObject("Hello")));
var httpHandler = RouterFunctions.toHttpHandler(route);
var adapter = new ReactorHttpHandlerAdapter(httpHandler);
var server = HttpServer.create().host("localhost").port(8080).handle(adapter).bindNow();
System.out.println("press enter");
Scanner sc = new Scanner(System.in);
sc.next();
server.disposeNow();
}
}
You can use the method block, as in:
DisposableServer server =
HttpServer.create()
.bindNow();
server.onDispose()
.block();
Read more in the Reactor Netty docs.
Although I integrated libraries in build.gradle but when I run it on device the following error occurs.
11-16 12:59:10.097 14630-14630/sadboy.antix E/AndroidRuntime: FATAL EXCEPTION: main
Process: sadboy.antix, PID: 14630
java.lang.NoClassDefFoundError: org.apache.lucene.util.AttributeSource$2
at org.apache.lucene.util.AttributeSource.<clinit>(AttributeSource.java:150)
at sadboy.antix.text_processing.KeywordsExtractor.getKeywordsList(KeywordsExtractor.java:34)
at sadboy.antix.activities.NewsArticle.onCreate(NewsArticle.java:51)
at android.app.Activity.performCreate(Activity.java:6010)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1129)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2292)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2413)
at android.app.ActivityThread.access$800(ActivityThread.java:155)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1317)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5343)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:905)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:700)
11-16 13:04:10.197 14630-14630/sadboy.antix I/Process: Sending signal. PID: 14630 SIG: 9
My code looks like this,
buidl.gradle
apply plugin: 'com.android.application'
android {
compileSdkVersion 25
buildToolsVersion "25.0.0"
defaultConfig {
applicationId "sadboy.antix"
minSdkVersion 16
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:25.0.0'
//Library for web scraping
compile 'org.jsoup:jsoup:1.10.1'
//Library for HTTP request
compile 'com.squareup.okhttp3:okhttp:3.4.2'
//Savage UX/UI libraries
compile 'com.mikhaellopez:circularfillableloaders:1.2.0'
compile 'com.squareup.picasso:picasso:2.5.2'
compile 'com.balysv:material-ripple:1.0.2'
compile('com.mikepenz:materialdrawer:5.7.0#aar') {
transitive = true
}
//Lucence libraries for text processing
compile group: 'org.apache.lucene', name: 'lucene-core', version: '5.5.0'
compile group: 'org.apache.lucene', name: 'lucene-analyzers-common', version: '5.5.0'
//Essential google libraries
compile 'com.android.support:cardview-v7:25.0.0'
compile 'com.android.support:recyclerview-v7:25.0.0'
compile 'com.android.support:design:25.0.0'
}
Classes where I am using Lucence
package sadboy.antix.text_processing;
/**
* Created by Varun Kumar on 11/15/2016.
*/
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.core.LowerCaseFilter;
import org.apache.lucene.analysis.core.StopFilter;
import org.apache.lucene.analysis.en.EnglishAnalyzer;
import org.apache.lucene.analysis.en.PorterStemFilter;
import org.apache.lucene.analysis.miscellaneous.ASCIIFoldingFilter;
import org.apache.lucene.analysis.standard.ClassicFilter;
import org.apache.lucene.analysis.standard.StandardTokenizer;
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
import java.io.IOException;
import java.io.StringReader;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
public class KeywordsExtractor {
public static List<CardKeyword> getKeywordsList(String fullText) throws IOException {
TokenStream tokenStream = null;
try {
fullText = fullText.replaceAll("-+", "-0");
fullText = fullText.replaceAll("[\\p{Punct}&&[^'-]]+", " ");
fullText = fullText.replaceAll("(?:'(?:[tdsm]|[vr]e|ll))+\\b", "");
StandardTokenizer stdToken = new StandardTokenizer();
stdToken.setReader(new StringReader(fullText));
tokenStream = new StopFilter(new ASCIIFoldingFilter(new ClassicFilter(new LowerCaseFilter(stdToken))), EnglishAnalyzer.getDefaultStopSet());
tokenStream.reset();
List<CardKeyword> cardKeywords = new LinkedList<>();
CharTermAttribute token = tokenStream.getAttribute(CharTermAttribute.class);
while (tokenStream.incrementToken()) {
String term = token.toString();
String stem = getStemForm(term);
if (stem != null) {
CardKeyword cardKeyword = find(cardKeywords, new CardKeyword(stem.replaceAll("-0", "-")));
cardKeyword.add(term.replaceAll("-0", "-"));
}
}
Collections.sort(cardKeywords);
return cardKeywords;
} finally {
if (tokenStream != null) {
try {
tokenStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
private static String getStemForm(String term) throws IOException {
TokenStream tokenStream = null;
try {
StandardTokenizer stdToken = new StandardTokenizer();
stdToken.setReader(new StringReader(term));
tokenStream = new PorterStemFilter(stdToken);
tokenStream.reset();
Set<String> stems = new HashSet<>();
CharTermAttribute token = tokenStream.getAttribute(CharTermAttribute.class);
while (tokenStream.incrementToken()) {
stems.add(token.toString());
}
if (stems.size() != 1) {
return null;
}
String stem = stems.iterator().next();
if (!stem.matches("[a-zA-Z0-9-]+")) {
return null;
}
return stem;
} finally {
if (tokenStream != null) {
try {
tokenStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
private static <T> T find(Collection<T> collection, T sample) {
for (T element : collection) {
if (element.equals(sample)) {
return element;
}
}
collection.add(sample);
return sample;
}
}
Model Class
package sadboy.antix.text_processing;
/**
* Created by Varun Kumar on 11/15/2016.
*/
import java.util.HashSet;
import java.util.Set;
public class CardKeyword implements Comparable<CardKeyword> {
private final String stem;
private final Set<String> terms = new HashSet<>();
private int frequency;
public CardKeyword(String stem) {
this.stem = stem;
}
public void add(String term) {
this.terms.add(term);
this.frequency++;
}
#Override
public int compareTo(CardKeyword keyword) {
return Integer.valueOf(keyword.frequency).compareTo(this.frequency);
}
#Override
public int hashCode() {
return this.getStem().hashCode();
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof CardKeyword)) return false;
CardKeyword that = (CardKeyword) o;
return this.getStem().equals(that.getStem());
}
public String getStem() {
return this.stem;
}
public Set<String> getTerms() {
return this.terms;
}
public int getFrequency() {
return this.frequency;
}
}
Activity where all this begins
package sadboy.antix.activities;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import java.io.IOException;
import java.util.List;
import sadboy.antix.R;
import sadboy.antix.text_processing.CardKeyword;
import sadboy.antix.text_processing.KeywordsExtractor;
public class NewsArticle extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_news_article);
String input = "Pick Flick is your ultimate app to find information about Movies, TV shows and Celebrities fast and easily on the go\n" +
"\n" +
"• Quick access of popular, top rated, now playing, highest grossing and upcoming movies\n" +
"• Quick access of popular, top rated, airing today and on air TV shows\n" +
"• View the cast of movies and TV shows\n" +
"• Similar Movies and TV shows to watch to explore more on the basis of your search\n" +
"• Find the movies or TV shows done by a celebrity\n" +
"• Set reminders and bookmarks so you never forget or miss anything you like\n" +
"• Share everything with your friends and family to plan movies or just watch a TV show maybe\n" +
"• List of trending celebrities\n" +
"• All the information and rating of Movies, TV shows and Celebrities on the go\n" +
"• Fast and easy search with keywords and suggestions\n" +
"• Fluid and easy to use UI enabling for glitch free experience\n" +
"\n" +
"• Like Pick Flick on Facebook\n" +
"• https://www.facebook.com/pickflickapp\n" +
"\n" +
"• Follow Pick Flick on Instagram\n" +
"• https://www.instagram.com/pickflickapp/\n" +
"\n" +
"• Pick Flick uses data and images by TMDb licensed under CC BY-NC 4.0\n" +
"• https://creativecommons.org/licenses/by-nc/4.0/\n" +
"\n" +
"• Pick Flick uses the TMDb API but is not endorsed or certified by TMDb\n" +
"• https://www.themoviedb.org/documentation/api/terms-of-use";
List<CardKeyword> keywordsList = null;
try {
keywordsList = KeywordsExtractor.getKeywordsList(input);
} catch (IOException e) {
e.printStackTrace();
}
int i;
for(i = 0;i<keywordsList.size();i++)
{
Log.d("Keyword",i+" "+keywordsList.get(i).getStem());
}
}
}
Pls check with adding this:
// https://mvnrepository.com/artifact/org.apache.lucene/lucene-backward-codecs
compile group: 'org.apache.lucene', name: 'lucene-backward-codecs', version: '5.5.0'