Skip to content

Task 6 [Simple Search Engine] with Static Code Analysis #3

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
# Done for Review
* @sasharmagrid
* @SajjadSidd
1 change: 1 addition & 0 deletions SCA/Readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<img width="847" alt="Screenshot 2025-02-11 at 2 07 46 PM" src="https://github.com/user-attachments/assets/b4ee6326-9e3b-4086-87f0-f1daed155c3b" />
68 changes: 68 additions & 0 deletions SCA/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>org.example</groupId>
<artifactId>com.testReport</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>

<name>com.testReport</name>
<url>http://maven.apache.org</url>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencies>
<!-- Example dependency -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<!-- Checkstyle Plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>3.6.0</version>
<executions>
<execution>
<phase>validate</phase> <!-- Run during validate phase -->
<goals>
<goal>check</goal> <!-- Goal to run Checkstyle -->
</goals>
</execution>
</executions>
<configuration>
<!-- Specify your Checkstyle configuration file -->
<configLocation>google_checks.xml</configLocation> <!-- or specify your own rules -->
<!-- <encoding>UTF-8</encoding>-->
<consoleOutput>true</consoleOutput>
<failOnViolation>true</failOnViolation> <!-- Set to false if you don't want to fail the build on violations -->
</configuration>
</plugin>
<plugin>
<groupId>com.github.spotbugs</groupId>
<artifactId>spotbugs-maven-plugin</artifactId>
<version>4.8.6.6</version>
<configuration>
<outputDirectory>target/spotbugs-report</outputDirectory>
<xmlOutput>true</xmlOutput>
<htmlOutput>true</htmlOutput>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>10</source>
<target>10</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
16 changes: 16 additions & 0 deletions SCA/src/main/java/org/example/search/Main.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package search;

import search.SimpleSearchEngine.Search;

class Main{
public static void main(String[] args) {
if (args.length == 2 && "--data".equals(args[0])) {
String fileName = args[1];
// String fileName = "/Users/hasingh/IdeaProjects/Simple Search Engine (Java)/Simple Search Engine (Java)/task/names.txt";
Search search = new Search();
search.getInput(fileName);
} else {
System.out.println("Usage: java Search --data <filename>");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.example.search.SearchEngineInterface;


import java.util.HashSet;
import java.util.Map;
import java.util.Set;

public class AllSearchStrategy implements SimpleSearchEngine {

@Override
public Set<Integer> search(String[] queryWords, Map<String, Set<Integer>> invertedIndex) {
Set<Integer> resultIndexes = new HashSet<>(invertedIndex.getOrDefault(queryWords[0], Set.of()));
for (int i = 1; i < queryWords.length; i++) {
resultIndexes.retainAll(invertedIndex.getOrDefault(queryWords[i], Set.of()));
}
return resultIndexes;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package org.example.search.SearchEngineInterface;

import java.util.HashSet;
import java.util.Map;
import java.util.Set;

public class AnySearchStrategy implements SimpleSearchEngine {

@Override
public Set<Integer> search(String[] queryWords, Map<String, Set<Integer>> invertedIndex) {
Set<Integer> resultIndexes = new HashSet<>();
for (String word : queryWords) {
resultIndexes.addAll(invertedIndex.getOrDefault(word, Set.of()));
}
return resultIndexes;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package org.example.search.SearchEngineInterface;


import java.util.HashSet;
import java.util.Map;
import java.util.Set;

public class NoneSearchStrategy implements SimpleSearchEngine {

@Override
public Set<Integer> search(String[] queryWords, Map<String, Set<Integer>> invertedIndex) {
Set<Integer> allIndexes = new HashSet<>();
invertedIndex.values().forEach(allIndexes::addAll);

Set<Integer> resultIndexes = new HashSet<>(allIndexes);
for (String word : queryWords) {
resultIndexes.removeAll(invertedIndex.getOrDefault(word, Set.of()));
}
return resultIndexes;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.example.search.SearchEngineInterface;

import java.util.Map;
import java.util.Set;

public interface SimpleSearchEngine {
public Set<Integer> search(String[] queryWords, Map<String, Set<Integer>> invertedIndex);

}

143 changes: 143 additions & 0 deletions SCA/src/main/java/org/example/search/SimpleSearchEngine/Search.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
package org.example.search.SimpleSearchEngine;

import org.example.search.SearchEngineInterface.AllSearchStrategy;
import org.example.search.SearchEngineInterface.AnySearchStrategy;
import org.example.search.SearchEngineInterface.NoneSearchStrategy;
import org.example.search.SearchEngineInterface.SimpleSearchEngine;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.*;

public class Search {

private SimpleSearchEngine searchStrategy;

// Set the search strategy at runtime
public void setSearchStrategy(SimpleSearchEngine searchStrategy) {
this.searchStrategy = searchStrategy;
}

public void getInput(String fileName) {
// Use a Scanner with UTF-8 encoding
Scanner sc = new Scanner(System.in, StandardCharsets.UTF_8);
ArrayList<String> nameWithMail = readFile(fileName);
if (nameWithMail.isEmpty()) {
System.out.println("No data found in the file.");
return;
}

Map<String, Set<Integer>> invertedIndex = buildInvertedIndex(nameWithMail);

while (true) {
System.out.println("\n=== MENU ===");
System.out.println("1. Find a person");
System.out.println("2. Print all people");
System.out.println("0. Exit");

int userChoice = sc.nextInt();
sc.nextLine(); // Consume the newline character

switch (userChoice) {
case 1:
System.out.println("\nSelect a matching strategy: ALL, ANY, NONE");
System.out.print("> ");
String strategy = sc.nextLine().toUpperCase().trim();

// Dynamically set the search strategy based on user input
switch (strategy) {
case "ALL":
setSearchStrategy(new AllSearchStrategy());
break;
case "ANY":
setSearchStrategy(new AnySearchStrategy());
break;
case "NONE":
setSearchStrategy(new NoneSearchStrategy());
break;
default:
System.out.println("Invalid strategy! Defaulting to ANY.");
setSearchStrategy(new AnySearchStrategy());
break;
}

System.out.println("\nEnter a name or email to search all suitable people.");
System.out.print("> ");
String query = sc.nextLine().toLowerCase().trim();

ArrayList<String> foundPeople = searchFoundPeople(query, invertedIndex, nameWithMail);
displayFoundPeople(foundPeople);
break;

case 2:
System.out.println("\n=== List of people ===");
displayFoundPeople(nameWithMail);
break;

case 0:
System.out.print("\nBye!");
return;

default:
System.out.println("\nIncorrect option! Try again.");
break;
}
}
}

private ArrayList<String> readFile(String fileName) {
ArrayList<String> nameWithMail = new ArrayList<>();
try (BufferedReader reader = new BufferedReader(new FileReader(fileName, StandardCharsets.UTF_8))) {
String line;
while ((line = reader.readLine()) != null) {
nameWithMail.add(line.trim());
}
} catch (IOException e) {
System.out.println("Error reading file: " + e.getMessage());
}
return nameWithMail;
}

private Map<String, Set<Integer>> buildInvertedIndex(ArrayList<String> nameWithMail) {
Map<String, Set<Integer>> invertedIndex = new HashMap<>();

for (int index = 0; index < nameWithMail.size(); index++) {
String line = nameWithMail.get(index);
String[] words = line.toLowerCase().split(" ");

for (String word : words) {
invertedIndex.putIfAbsent(word, new HashSet<>());
invertedIndex.get(word).add(index);
}
}

return invertedIndex;
}

public ArrayList<String> searchFoundPeople(String query, Map<String, Set<Integer>> invertedIndex, ArrayList<String> nameWithMail) {
String[] queryWords = query.split(" ");

// Use the current strategy to perform the search
Set<Integer> resultIndexes = searchStrategy.search(queryWords, invertedIndex);

ArrayList<String> foundPeople = new ArrayList<>();
for (int index : resultIndexes) {
foundPeople.add(nameWithMail.get(index));
}
return foundPeople;
}

public void displayFoundPeople(ArrayList<String> foundPeople) {
if (foundPeople.isEmpty()) {
System.out.println("No matching people found.");
} else {
System.out.println(foundPeople.size() + " persons found:");
for (String person : foundPeople) {
System.out.println(person);
}
}
}
}
8 changes: 8 additions & 0 deletions SCA/src/test/java/org/example/AppTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package org.example;


/**
* Unit test for simple App.
*/
public class AppTest {
}
4 changes: 4 additions & 0 deletions SCA/target/checkstyle-cachefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#Tue Feb 11 11:09:05 IST 2025
configuration*?=DF49F0FE5B9B10DC7D619307077AB41F3A1D6CA4
module-resource*?\:checkstyle-xpath-suppressions.xml=FA903F3273968553608AED7EAA3A7AD969B0A598
module-resource*?\:checkstyle-suppressions.xml=8E483F9CA10CB1377DC49BE8CF79425FD801210
Loading