diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f834805 --- /dev/null +++ b/.gitignore @@ -0,0 +1,30 @@ +# Maven build output +target/ + +# Maven Wrapper JAR +.mvn/wrapper/maven-wrapper.jar + +# Java compiled files +*.class + +# IDE files +.idea/ +*.iml +.project +.classpath +.settings/ +.vscode/ +*.swp +*.swo + +# OS files +.DS_Store +Thumbs.db + +# Python testing artifacts +.venv/ +venv/ +__pycache__/ +.pytest_cache/ +*.pyc +*.pyo diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 0000000..e70e7bc --- /dev/null +++ b/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1,2 @@ +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.6/apache-maven-3.9.6-bin.zip +wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar diff --git a/README.md b/README.md old mode 100644 new mode 100755 index a15708e..bcd0a52 --- a/README.md +++ b/README.md @@ -1,157 +1,66 @@ - +# Email Slicer — Java 17 -# Email Slicer Using Python - -Email Slicer is a simple tool where the email address is provided as an input and the application returns the username and the domain of the email address as an output. It makes use of the slicing operation in Python. - - +Email Slicer is a simple tool where an email address is provided as input and the application returns the username and the domain of the email address as output. Migrated from the original Python implementation to idiomatic Java 17. ## Built With -![Python][python-shield] +- Java 17 (OpenJDK) +- Maven 3.9+ (via Maven Wrapper) +- JUnit 5 (testing) - +## Prerequisites -## Example +- Java 17 or later installed (`java -version` to check) +- No Maven installation required — the Maven Wrapper (`mvnw`) is included -Input: -``` -Please enter your Email Id: -avimax37@gmail.com -``` +## Build -Output: -``` -Your username is: avimax37 -Your domain is: gmail.com +```bash +./mvnw package ``` -Here we got **`avimax37`** as username and **`gmail.com`** as domain. - - - -## Installation - -Use the link to download Python. - -[![Python][python-shield]][python-url] +## Run -Use the link to download PyCharm. - -[![PyCharm][pycharm-shield]][pycharm-url] - -Use the link to download Visual Studio Code. - -[![Visual Studio Code][visual studio code-shield]][visual studio code-url] - - - -## Usage - -Open Command Prompt or Windows PowerShell to start. - -```python -# get into python mode -python - -# create a python script -hello.py -print("Hello World") - -# go to the file path -cd - -# run the script -python hello.py +```bash +java -jar target/email-slicer.jar ``` -VS Code or PyCharm can also be used. - - +## Test -## Code - -So at first we are going to ask the user to enter the email that is to be sliced. - -```python -print("Please enter your Email Id:") -email = input().strip() +```bash +./mvnw test ``` -Here, as usual, we are making use of the **`input()`** function to get the input from the user in form of a string. We will store this input string in **`email`** variable. - -Also we are making use of the **`strip()`** function. **`strip()`** function will remove any additional & unwanted spacing on both sides of the input string. So that we can make sure that we have only the email in the input and not any unwanted spaces. +## Example -```python -if email.find("@") != -1: +Input: ``` - -Here we are checking if the input string contains **`@`** or not. If it contains **`@`**, then it is considered as a valid email id and we move to the next step, which is slicing the email. - -```python -username = email[:email.index("@")] -domain = email[email.index("@") + 1:] +Please enter your Email Id: +avimax37@gmail.com ``` -Now, we print the **`username`** and **`domain`** to show the result. - -```python -print("Your username is: ", username) -print("Your domain is: ", domain) +Output: ``` - -If the input string does not contain **`@`**, then it is considered as an invalid email id and we get out of the loop with a warning message. - -```python -else: - print("Please enter a valid Email Id.") +Your username is: avimax37 +Your domain is: gmail.com ``` - - -## Logic - -Let's consider the input is **`avimax37@gmail.com`**, so when we write **`email[email.index("@"):]`**, our **`index()`** function will interpret it as **`email[:8]`** as our **`@`** is located at index **8**. Now **`email[:8]`** knows that **`@`** is located at index **8**, so now it will keep the part before index **8** and discard the rest. It will store the stripped value in **`username`**. +Here we got **`avimax37`** as username and **`gmail.com`** as domain. -This exact same process is followed for **`domain`** also. +## Project Structure - +``` +├── pom.xml # Maven build configuration +├── mvnw / mvnw.cmd # Maven Wrapper scripts +├── src/main/java/com/emailslicer/ +│ ├── Main.java # Console I/O entry point +│ ├── EmailSlicer.java # Pure parsing logic +│ ├── EmailSlicerResult.java # Record holding username + domain +│ └── Messages.java # User-facing string constants +└── src/test/java/com/emailslicer/ + └── EmailSlicerTest.java # JUnit 5 unit tests +``` ## License Distributed under the MIT License. See **`LICENSE.md`** for more information. - - - -## Contact - -Avinaba Bera - -[![Twitter][twitter-shield]][twitter-url] -[![LinkedIn][linkedin-shield]][linkedin-url] - - - -## Project Links - -[![GitHub][github-shield]][github-url] - - - -[python-shield]: https://img.shields.io/badge/python-3670A0?style=for-the-badge&logo=python&logoColor=ffdd54 -[python-url]: https://www.python.org/downloads - -[pycharm-shield]: https://img.shields.io/badge/pycharm-143?style=for-the-badge&logo=pycharm&logoColor=black&color=black&labelColor=green -[pycharm-url]: https://www.jetbrains.com/pycharm/download/#section=windows - -[visual studio code-shield]: https://img.shields.io/badge/Visual%20Studio%20Code-0078d7.svg?style=for-the-badge&logo=visual-studio-code&logoColor=white -[visual studio code-url]: https://code.visualstudio.com/download - -[twitter-shield]: https://img.shields.io/badge/Twitter-%231DA1F2.svg?style=for-the-badge&logo=Twitter&logoColor=white -[twitter-url]: https://twitter.com/IainSchneider - -[linkedin-shield]: https://img.shields.io/badge/linkedin-%230077B5.svg?style=for-the-badge&logo=linkedin&logoColor=white -[linkedin-url]: https://www.linkedin.com/in/avinaba-bera - -[github-shield]: https://img.shields.io/badge/github-%23121011.svg?style=for-the-badge&logo=github&logoColor=white -[github-url]: https://github.com/avimax37/email-slicer-python diff --git a/mvnw b/mvnw new file mode 100755 index 0000000..205a0ac --- /dev/null +++ b/mvnw @@ -0,0 +1,265 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Apache Maven Wrapper startup batch script, version 3.2.0 +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /usr/local/etc/mavenrc ] ; then + . /usr/local/etc/mavenrc + fi + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +mingw=false +case "$(uname)" in + CYGWIN*) cygwin=true ;; + MINGW*) mingw=true;; + Darwin*) darwin=true + # Use /usr/libexec/java_home if available, otherwise fall back + # to /Library/Java/Home + # See https://developer.apple.com/library/mac/qa/qa1170/_index.html + if [ -z "$JAVA_HOME" ]; then + if [ -x "/usr/libexec/java_home" ]; then + JAVA_HOME="$(/usr/libexec/java_home)"; export JAVA_HOME + else + JAVA_HOME="/Library/Java/Home"; export JAVA_HOME + fi + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=$(java-config --jre-home) + fi +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$JAVA_HOME" ] && + JAVA_HOME=$(cygpath --unix "$JAVA_HOME") + [ -n "$CLASSPATH" ] && + CLASSPATH=$(cygpath --path --unix "$CLASSPATH") +fi + +# For Mingw, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$JAVA_HOME" ] && [ -d "$JAVA_HOME" ] && + JAVA_HOME="$(cd "$JAVA_HOME" || (echo "cannot cd into $JAVA_HOME."; exit 1); pwd)" +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="$(which javac)" + if [ -n "$javaExecutable" ] && ! [ "$(expr "$javaExecutable" : '\([^ ]*\)')" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=$(which readlink) + if [ ! "$(expr "$readLink" : '\([^ ]*\)')" = "no" ]; then + if $darwin ; then + javaHome="$(dirname "$javaExecutable")" + javaExecutable="$(cd "$javaHome" && pwd -P)/javac" + else + javaExecutable="$(readlink -f "$javaExecutable")" + fi + javaHome="$(dirname "$javaExecutable")" + javaHome=$(expr "$javaHome" : '\(.*\)/bin') + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD="$(\unset -f command 2>/dev/null; \command -v java)" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + if [ -z "$1" ] + then + echo "Path not specified to find_maven_basedir" + return 1 + fi + + basedir="$1" + wdir="$1" + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + # workaround for JBEAP-8://://wn/teletrack + if [ -d "${wdir}" ]; then + wdir=$(cd "$wdir/.." || exit 1; pwd) + fi + # end of workaround + done + printf '%s' "$(cd "$basedir" || exit 1; pwd)" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + echo "$(tr -s '\n' ' ' < "$1")" + fi +} + +BASE_DIR=$(find_maven_basedir "$(dirname "$0")") +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}; export MAVEN_PROJECTBASEDIR +if [ "$MVNW_VERBOSE" = true ]; then + echo $MAVEN_PROJECTBASEDIR +fi + +########################################################################################## +# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +# This allows using the maven wrapper in projects that prohibit checking in binary data. +########################################################################################## +wrapperJarPath="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" +if [ -r "$wrapperJarPath" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found $wrapperJarPath" + fi +else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Couldn't find $wrapperJarPath, downloading it ..." + fi + + if [ -n "$MVNW_REPOURL" ]; then + wrapperUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" + else + wrapperUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" + fi + while IFS="=" read -r key value; do + # Remove '\r' from value (in case of Windows-style line endings) + value=$(echo "$value" | tr -d '\r') + case "$key" in (wrapperUrl) wrapperUrl="$value"; break ;; + esac + done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties" + if [ "$MVNW_VERBOSE" = true ]; then + echo "Downloading from: $wrapperUrl" + fi + + if $cygwin; then + wrapperJarPath=$(cygpath --path --windows "$wrapperJarPath") + fi + + if command -v wget > /dev/null; then + QUIET="" + if [ "$MVNW_VERBOSE" != true ]; then + QUIET="--quiet" + fi + if ! wget $QUIET -O "$wrapperJarPath" "$wrapperUrl" -t 3; then + rm -f "$wrapperJarPath" + echo "ERROR: Failed to download Maven Wrapper JAR from $wrapperUrl" >&2 + exit 1 + fi + elif command -v curl > /dev/null; then + QUIET="" + if [ "$MVNW_VERBOSE" != true ]; then + QUIET="--silent" + fi + if ! curl $QUIET -o "$wrapperJarPath" "$wrapperUrl" -f -L; then + rm -f "$wrapperJarPath" + echo "ERROR: Failed to download Maven Wrapper JAR from $wrapperUrl" >&2 + exit 1 + fi + else + echo "ERROR: Neither wget nor curl found to download Maven Wrapper JAR" >&2 + exit 1 + fi +fi +########################################################################################## +# End of extension +########################################################################################## + +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$JAVA_HOME" ] && + JAVA_HOME=$(cygpath --path --windows "$JAVA_HOME") + [ -n "$CLASSPATH" ] && + CLASSPATH=$(cygpath --path --windows "$CLASSPATH") + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=$(cygpath --path --windows "$MAVEN_PROJECTBASEDIR") +fi + +# Provide a "standardized" way to retrieve the CLI args that will +# work with both Windows and non-Windows executions. +MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $*" +export MAVEN_CMD_LINE_ARGS + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +# shellcheck disable=SC2086 +exec "$JAVACMD" \ + $MAVEN_OPTS \ + $MAVEN_DEBUG_OPTS \ + -classpath "$wrapperJarPath" \ + "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CMD_LINE_ARGS diff --git a/mvnw.cmd b/mvnw.cmd new file mode 100644 index 0000000..200a61d --- /dev/null +++ b/mvnw.cmd @@ -0,0 +1,200 @@ +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Apache Maven Wrapper startup batch script, version 3.2.0 +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM://Lines with '@' +@echo off +@REM set title of command window +title %0 +@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%"=="on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%"=="" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %* +if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %* +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%"=="" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +set WRAPPER_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" + +FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( + IF "%%A"=="wrapperUrl" SET WRAPPER_URL=%%B +) + +@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +@REM This allows using the maven wrapper in projects that prohibit checking in binary data. +if exist %WRAPPER_JAR% ( + if "%MVNW_VERBOSE%" == "true" ( + echo Found %WRAPPER_JAR% + ) +) else ( + if not "%MVNW_REPOURL%" == "" ( + SET WRAPPER_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" + ) + if "%MVNW_VERBOSE%" == "true" ( + echo Downloading from: %WRAPPER_URL% + ) + + powershell -Command "&{"^ + "$webclient = new-object System.Net.WebClient;"^ + "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ + "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ + "}"^ + "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%WRAPPER_URL%', '%WRAPPER_JAR%')"^ + "}" + if "%MVNW_VERBOSE%" == "true" ( + echo Finished downloading %WRAPPER_JAR% + ) +) +@REM End of extension + +@REM If specified, validate the SHA-256 sum of the Maven wrapper jar file +SET WRAPPER_SHA_256_SUM="" +FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( + IF "%%A"=="wrapperSha256Sum" SET WRAPPER_SHA_256_SUM=%%B +) +IF NOT %WRAPPER_SHA_256_SUM%=="" ( + powershell -Command "&{"^ + "$hash = (Get-FileHash \"%WRAPPER_JAR%\" -Algorithm SHA256).Hash.ToLower();"^ + "If('%WRAPPER_SHA_256_SUM%' -ne $hash){"^ + " Write-Output 'Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be tampered.';"^ + " Write-Output 'Investigate or delete %WRAPPER_JAR% to attempt a clean download.';"^ + " Write-Output 'If you updated your Maven version, you need to update the specified wrapperSha256Sum property.';"^ + " exit 1;"^ + "}"^ + "}" + if ERRORLEVEL 1 goto error +) + +%MAVEN_JAVA_EXE% ^ + %JVM_CONFIG_MAVEN_PROPS% ^ + %MAVEN_OPTS% ^ + %MAVEN_DEBUG_OPTS% ^ + -classpath %WRAPPER_JAR% ^ + "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^ + %WRAPPER_LAUNCHER% %MAVEN_CMD_LINE_ARGS% +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat" +if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%"=="on" pause + +if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE% + +cmd /C exit /B %ERROR_CODE% diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..7370fd3 --- /dev/null +++ b/pom.xml @@ -0,0 +1,62 @@ + + + 4.0.0 + + com.emailslicer + email-slicer + 1.0.0 + jar + + Email Slicer + A simple tool that slices an email address into username and domain + + + UTF-8 + 17 + 17 + 5.10.2 + + + + + org.junit.jupiter + junit-jupiter + ${junit.version} + test + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.11.0 + + 17 + 17 + + + + org.apache.maven.plugins + maven-surefire-plugin + 3.2.5 + + + org.apache.maven.plugins + maven-jar-plugin + 3.3.0 + + + + com.emailslicer.Main + + + email-slicer + + + + + diff --git a/src/main/java/com/emailslicer/EmailSlicer.java b/src/main/java/com/emailslicer/EmailSlicer.java new file mode 100644 index 0000000..d584242 --- /dev/null +++ b/src/main/java/com/emailslicer/EmailSlicer.java @@ -0,0 +1,47 @@ +package com.emailslicer; + +import java.util.Optional; + +/** + * Pure parsing logic for slicing an email address into username and domain. + * This class contains no I/O — it operates on strings only. + * + *

The current implementation mirrors the Python original's behavior: + * it splits on the first '@' character found in the input. More rigorous + * validation (e.g., regex-based) is planned for a future milestone.

+ */ +public final class EmailSlicer { + + private EmailSlicer() { + // Prevent instantiation + } + + /** + * Slices an email address into its username and domain components. + * + *

The input is stripped of leading/trailing whitespace before processing. + * The split is performed on the first occurrence of '@', matching the + * behavior of the original Python implementation.

+ * + * @param email the email address to slice + * @return an {@link Optional} containing the result if the email contains '@', + * or {@link Optional#empty()} if the input is null, blank, or lacks '@' + */ + public static Optional slice(String email) { + if (email == null || email.isBlank()) { + return Optional.empty(); + } + + String trimmed = email.strip(); + int atIndex = trimmed.indexOf('@'); + + if (atIndex == -1) { + return Optional.empty(); + } + + String username = trimmed.substring(0, atIndex); + String domain = trimmed.substring(atIndex + 1); + + return Optional.of(new EmailSlicerResult(username, domain)); + } +} diff --git a/src/main/java/com/emailslicer/EmailSlicerResult.java b/src/main/java/com/emailslicer/EmailSlicerResult.java new file mode 100644 index 0000000..b15e52a --- /dev/null +++ b/src/main/java/com/emailslicer/EmailSlicerResult.java @@ -0,0 +1,11 @@ +package com.emailslicer; + +/** + * Immutable record holding the result of slicing an email address + * into its username and domain components. + * + * @param username the part before the '@' symbol + * @param domain the part after the '@' symbol + */ +public record EmailSlicerResult(String username, String domain) { +} diff --git a/src/main/java/com/emailslicer/Main.java b/src/main/java/com/emailslicer/Main.java new file mode 100644 index 0000000..11eb4ed --- /dev/null +++ b/src/main/java/com/emailslicer/Main.java @@ -0,0 +1,33 @@ +package com.emailslicer; + +import java.util.Optional; +import java.util.Scanner; + +/** + * Console entry point for the Email Slicer application. + * Prompts the user for an email address, slices it, and prints the result. + * + *

This class is the Java equivalent of the original Python script's + * top-level I/O logic.

+ */ +public class Main { + + public static void main(String[] args) { + System.out.println(Messages.PROMPT_EMAIL); + + try (Scanner scanner = new Scanner(System.in)) { + String email = scanner.nextLine().strip(); + + Optional result = EmailSlicer.slice(email); + + if (result.isPresent()) { + EmailSlicerResult sliced = result.get(); + System.out.println(Messages.USERNAME_PREFIX + sliced.username()); + System.out.println(Messages.DOMAIN_PREFIX + sliced.domain()); + } else { + System.out.println(Messages.INVALID_EMAIL); + System.exit(1); + } + } + } +} diff --git a/src/main/java/com/emailslicer/Messages.java b/src/main/java/com/emailslicer/Messages.java new file mode 100644 index 0000000..63734bc --- /dev/null +++ b/src/main/java/com/emailslicer/Messages.java @@ -0,0 +1,16 @@ +package com.emailslicer; + +/** + * Centralized user-facing messages for the Email Slicer application. + */ +public final class Messages { + + public static final String PROMPT_EMAIL = "Please enter your Email Id:"; + public static final String USERNAME_PREFIX = "Your username is: "; + public static final String DOMAIN_PREFIX = "Your domain is: "; + public static final String INVALID_EMAIL = "Please enter a valid Email Id."; + + private Messages() { + // Prevent instantiation + } +} diff --git a/src/test/java/com/emailslicer/EmailSlicerTest.java b/src/test/java/com/emailslicer/EmailSlicerTest.java new file mode 100644 index 0000000..1960be9 --- /dev/null +++ b/src/test/java/com/emailslicer/EmailSlicerTest.java @@ -0,0 +1,117 @@ +package com.emailslicer; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; +import org.junit.jupiter.params.provider.NullAndEmptySource; +import org.junit.jupiter.params.provider.ValueSource; + +import java.util.Optional; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * Unit tests for {@link EmailSlicer}. + * + *

Tests cover valid email splitting and basic invalid inputs. + * The current milestone validates splitting on the first '@', + * matching the Python original's behavior.

+ */ +class EmailSlicerTest { + + @ParameterizedTest(name = "slice(\"{0}\") -> username={1}, domain={2}") + @DisplayName("Should return username and domain for valid emails") + @CsvSource({ + "avimax37@gmail.com, avimax37, gmail.com", + "first.last@example.org, first.last, example.org", + "user@mail.example.co.uk, user, mail.example.co.uk", + }) + void shouldReturnUsernameAndDomain_whenEmailIsValid(String email, + String expectedUsername, + String expectedDomain) { + Optional result = EmailSlicer.slice(email); + + assertTrue(result.isPresent(), "Expected a result for: " + email); + assertEquals(expectedUsername, result.get().username()); + assertEquals(expectedDomain, result.get().domain()); + } + + @Test + @DisplayName("Should strip whitespace before slicing") + void shouldStripWhitespace_whenEmailHasSurroundingSpaces() { + Optional result = EmailSlicer.slice(" user@test.com "); + + assertTrue(result.isPresent()); + assertEquals("user", result.get().username()); + assertEquals("test.com", result.get().domain()); + } + + @Test + @DisplayName("Should split on the first '@' when multiple '@' signs are present") + void shouldSplitOnFirstAt_whenMultipleAtSigns() { + // Matches Python behavior: index("@") returns the first occurrence + Optional result = EmailSlicer.slice("a@b@c.com"); + + assertTrue(result.isPresent()); + assertEquals("a", result.get().username()); + assertEquals("b@c.com", result.get().domain()); + } + + @ParameterizedTest(name = "slice(\"{0}\") -> empty") + @DisplayName("Should return empty for emails missing '@'") + @ValueSource(strings = {"invalidemail.com", "justtext"}) + void shouldReturnEmpty_whenNoAtSign(String email) { + Optional result = EmailSlicer.slice(email); + + assertTrue(result.isEmpty(), "Expected empty for: " + email); + } + + @ParameterizedTest(name = "slice({0}) -> empty") + @DisplayName("Should return empty for null and empty inputs") + @NullAndEmptySource + void shouldReturnEmpty_whenNullOrEmpty(String email) { + Optional result = EmailSlicer.slice(email); + + assertTrue(result.isEmpty()); + } + + @Test + @DisplayName("Should return empty for blank/whitespace-only input") + void shouldReturnEmpty_whenBlankInput() { + Optional result = EmailSlicer.slice(" "); + + assertTrue(result.isEmpty()); + } + + @Test + @DisplayName("Should handle '@' at the start of input") + void shouldHandleAtAtStart() { + Optional result = EmailSlicer.slice("@domain.com"); + + assertTrue(result.isPresent()); + assertEquals("", result.get().username()); + assertEquals("domain.com", result.get().domain()); + } + + @Test + @DisplayName("Should handle '@' at the end of input") + void shouldHandleAtAtEnd() { + Optional result = EmailSlicer.slice("user@"); + + assertTrue(result.isPresent()); + assertEquals("user", result.get().username()); + assertEquals("", result.get().domain()); + } + + @Test + @DisplayName("Should handle only '@' character") + void shouldHandleOnlyAtSign() { + // Python behavior: "@" contains '@', so it splits into empty username and empty domain + Optional result = EmailSlicer.slice("@"); + + assertTrue(result.isPresent()); + assertEquals("", result.get().username()); + assertEquals("", result.get().domain()); + } +}