diff options
Diffstat (limited to 'theme-test.java')
| -rw-r--r-- | theme-test.java | 461 |
1 files changed, 461 insertions, 0 deletions
diff --git a/theme-test.java b/theme-test.java new file mode 100644 index 000000000..7c1b582af --- /dev/null +++ b/theme-test.java @@ -0,0 +1,461 @@ +package com.example.theme; + +import java.util.*; +import java.util.concurrent.*; +import java.util.function.*; +import java.util.stream.*; +import java.time.*; +import java.time.format.*; +import java.net.*; +import java.io.*; +import java.nio.file.*; +import java.sql.*; +import java.lang.annotation.*; +import java.math.BigDecimal; +import java.math.BigInteger; + +// Enum definition +public enum LogLevel { + DEBUG(0, "Debug"), + INFO(1, "Info"), + WARN(2, "Warning"), + ERROR(3, "Error"); + + private final int level; + private final String description; + + LogLevel(int level, String description) { + this.level = level; + this.description = description; + } + + public int getLevel() { return level; } + public String getDescription() { return description; } +} + +// Interface with generics +public interface Repository<T extends Entity> { + Optional<T> findById(Long id); + List<T> findAll(); + T save(T entity); + void delete(Long id); + Stream<T> stream(); + + @FunctionalInterface + interface Predicate<T> { + boolean test(T t); + } +} + +// Abstract class +public abstract class AbstractService<T extends Entity> implements Repository<T> { + protected final Map<Long, T> cache = new ConcurrentHashMap<>(); + protected volatile boolean initialized = false; + + @Override + public Optional<T> findById(Long id) { + return Optional.ofNullable(cache.get(id)); + } + + @Override + public List<T> findAll() { + return new ArrayList<>(cache.values()); + } + + @Override + public Stream<T> stream() { + return cache.values().stream(); + } + + protected abstract void validate(T entity) throws ValidationException; +} + +// Annotation definition +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE, ElementType.METHOD}) +public @interface Service { + String value() default ""; + boolean transactional() default true; + Class<?>[] exceptions() = {}; +} + +// Record class (Java 14+) +public record User( + Long id, + String username, + String email, + @Deprecated String fullName, + LocalDateTime createdAt, + boolean active +) implements Entity { + + public User { + Objects.requireNonNull(username, "Username cannot be null"); + Objects.requireNonNull(email, "Email cannot be null"); + Objects.requireNonNull(createdAt, "Created date cannot be null"); + } + + public static User of(String username, String email) { + return new User(null, username, email, null, LocalDateTime.now(), true); + } + + public User withId(Long id) { + return new User(id, username, email, fullName, createdAt, active); + } +} + +// Exception classes +public class ValidationException extends RuntimeException { + private final List<String> errors; + + public ValidationException(String message) { + super(message); + this.errors = List.of(message); + } + + public ValidationException(List<String> errors) { + super(String.join(", ", errors)); + this.errors = Collections.unmodifiableList(errors); + } + + public List<String> getErrors() { return errors; } +} + +public class ResourceNotFoundException extends RuntimeException { + public ResourceNotFoundException(String resource, Long id) { + super(String.format("%s with id %d not found", resource, id)); + } +} + +// Service implementation +@Service(value = "userService", transactional = true) +public class UserService extends AbstractService<User> { + + private static final Logger logger = LoggerFactory.getLogger(UserService.class); + private static final int MAX_RETRY_ATTEMPTS = 3; + private static final Duration TIMEOUT = Duration.ofSeconds(30); + + private final EmailService emailService; + private final UserRepository userRepository; + private final PasswordEncoder passwordEncoder; + + @Inject + public UserService(EmailService emailService, + UserRepository userRepository, + PasswordEncoder passwordEncoder) { + this.emailService = emailService; + this.userRepository = userRepository; + this.passwordEncoder = passwordEncoder; + } + + @Override + protected void validate(User user) throws ValidationException { + List<String> errors = new ArrayList<>(); + + if (user.username() == null || user.username().trim().isEmpty()) { + errors.add("Username is required"); + } else if (!user.username().matches("^[a-zA-Z0-9_]{3,20}$")) { + errors.add("Username must be 3-20 characters, alphanumeric and underscore only"); + } + + if (user.email() == null || !user.email().matches("^[A-Za-z0-9+_.-]+@(.+)$")) { + errors.add("Valid email is required"); + } + + if (!errors.isEmpty()) { + throw new ValidationException(errors); + } + } + + @Transactional + public User createUser(CreateUserRequest request) throws ValidationException { + logger.info("Creating new user: {}", request.username()); + + // Check if user already exists + if (userRepository.findByUsername(request.username()).isPresent()) { + throw new ValidationException("Username already exists"); + } + + if (userRepository.findByEmail(request.email()).isPresent()) { + throw new ValidationException("Email already exists"); + } + + // Create new user + User user = User.of(request.username(), request.email()) + .withId(generateId()); + + validate(user); + + try { + User savedUser = userRepository.save(user); + cache.put(savedUser.id(), savedUser); + + // Send welcome email asynchronously + CompletableFuture.runAsync(() -> + emailService.sendWelcomeEmail(savedUser) + ).exceptionally(throwable -> { + logger.error("Failed to send welcome email to user {}", savedUser.id(), throwable); + return null; + }); + + logger.info("Successfully created user with ID: {}", savedUser.id()); + return savedUser; + + } catch (DataAccessException e) { + logger.error("Database error while creating user", e); + throw new ServiceException("Failed to create user", e); + } + } + + public Optional<User> findByUsername(String username) { + return cache.values().stream() + .filter(user -> user.username().equals(username)) + .findFirst(); + } + + public List<User> findActiveUsers() { + return cache.values().stream() + .filter(User::active) + .sorted(Comparator.comparing(User::createdAt).reversed()) + .collect(Collectors.toList()); + } + + @Retry(maxAttempts = MAX_RETRY_ATTEMPTS, backoff = @Backoff(delay = 1000)) + public User updateUser(Long id, UpdateUserRequest request) { + User existingUser = findById(id) + .orElseThrow(() -> new ResourceNotFoundException("User", id)); + + User updatedUser = new User( + id, + request.username() != null ? request.username() : existingUser.username(), + request.email() != null ? request.email() : existingUser.email(), + existingUser.fullName(), + existingUser.createdAt(), + request.active() != null ? request.active() : existingUser.active() + ); + + validate(updatedUser); + + try { + User savedUser = userRepository.save(updatedUser); + cache.put(id, savedUser); + return savedUser; + } catch (DataAccessException e) { + logger.error("Failed to update user with ID: {}", id, e); + throw new ServiceException("Failed to update user", e); + } + } + + @Async + public CompletableFuture<Void> deleteUser(Long id) { + return CompletableFuture.runAsync(() -> { + try { + userRepository.deleteById(id); + cache.remove(id); + logger.info("Successfully deleted user with ID: {}", id); + } catch (DataAccessException e) { + logger.error("Failed to delete user with ID: {}", id, e); + throw new ServiceException("Failed to delete user", e); + } + }); + } + + private Long generateId() { + return System.currentTimeMillis() + (long)(Math.random() * 1000); + } +} + +// Utility class +public final class DateUtils { + + private DateUtils() { + // Utility class - prevent instantiation + } + + private static final DateTimeFormatter ISO_FORMATTER = + DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSXXX"); + + public static String formatIsoDateTime(LocalDateTime dateTime) { + return dateTime.atZone(ZoneId.systemDefault()).format(ISO_FORMATTER); + } + + public static LocalDateTime parseIsoDateTime(String isoString) { + return LocalDateTime.parse(isoString, ISO_FORMATTER); + } + + public static boolean isWithinLastDays(LocalDateTime dateTime, int days) { + return dateTime.isAfter(LocalDateTime.now().minusDays(days)); + } +} + +// Builder pattern +public class UserQueryBuilder { + private String username; + private String email; + private Boolean active; + private LocalDateTime createdAfter; + private LocalDateTime createdBefore; + private SortOrder sortOrder = SortOrder.ASC; + private String sortBy = "createdAt"; + private int limit = 100; + private int offset = 0; + + public UserQueryBuilder withUsername(String username) { + this.username = username; + return this; + } + + public UserQueryBuilder withEmail(String email) { + this.email = email; + return this; + } + + public UserQueryBuilder activeOnly(boolean active) { + this.active = active; + return this; + } + + public UserQueryBuilder createdAfter(LocalDateTime date) { + this.createdAfter = date; + return this; + } + + public UserQueryBuilder createdBefore(LocalDateTime date) { + this.createdBefore = date; + return this; + } + + public UserQueryBuilder sortBy(String field, SortOrder order) { + this.sortBy = field; + this.sortOrder = order; + return this; + } + + public UserQueryBuilder limit(int limit) { + this.limit = Math.max(1, Math.min(limit, 1000)); + return this; + } + + public UserQueryBuilder offset(int offset) { + this.offset = Math.max(0, offset); + return this; + } + + public UserQuery build() { + return new UserQuery(username, email, active, createdAfter, createdBefore, + sortBy, sortOrder, limit, offset); + } +} + +// Lambda expressions and streams +public class StreamProcessor { + + private static final Map<String, Function<String, Object>> TYPE_CONVERTERS = Map.of( + "string", s -> s, + "int", Integer::parseInt, + "double", Double::parseDouble, + "boolean", Boolean::parseBoolean, + "bigdecimal", BigDecimal::new, + "bigint", BigInteger::new + ); + + public Map<String, Object> processConfig(Properties properties) { + return properties.entrySet().stream() + .filter(entry -> entry.getKey() instanceof String) + .filter(entry -> entry.getValue() != null) + .collect(Collectors.toMap( + entry -> (String) entry.getKey(), + entry -> convertValue((String) entry.getKey(), (String) entry.getValue()) + )); + } + + private Object convertValue(String key, String value) { + String type = determineType(key, value); + return TYPE_CONVERTERS.getOrDefault(type, Function.identity()).apply(value); + } + + private String determineType(String key, String value) { + if (value.equalsIgnoreCase("true") || value.equalsIgnoreCase("false")) { + return "boolean"; + } else if (value.matches("-?\\d+")) { + return "int"; + } else if (value.matches("-?\\d*\\.\\d+")) { + return "double"; + } else if (key.toLowerCase().contains("amount") || key.toLowerCase().contains("price")) { + return "bigdecimal"; + } + return "string"; + } + + public List<String> validateEmails(List<String> emails) { + return emails.stream() + .filter(Objects::nonNull) + .map(String::trim) + .filter(email -> !email.isEmpty()) + .filter(email -> email.matches("^[A-Za-z0-9+_.-]+@(.+)$")) + .distinct() + .collect(Collectors.toList()); + } + + public CompletableFuture<List<User>> processUsersAsync(List<User> users) { + return CompletableFuture.supplyAsync(() -> + users.parallelStream() + .filter(User::active) + .filter(user -> user.createdAt().isAfter(LocalDateTime.now().minusYears(1))) + .sorted(Comparator.comparing(User::username)) + .collect(Collectors.toList()) + ); + } +} + +// Main class for testing +public class Main { + private static final Logger logger = LoggerFactory.getLogger(Main.class); + + public static void main(String[] args) { + try { + // Initialize application context + ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); + + // Get service bean + UserService userService = context.getBean(UserService.class); + + // Create test users + List<User> users = Arrays.asList( + User.of("john_doe", "[email protected]"), + User.of("jane_smith", "[email protected]"), + User.of("bob_wilson", "[email protected]") + ); + + // Process users + List<CompletableFuture<User>> futures = users.stream() + .map(user -> { + try { + return CompletableFuture.completedFuture(userService.createUser( + new CreateUserRequest(user.username(), user.email()) + )); + } catch (ValidationException e) { + logger.error("Failed to create user: {}", user.username(), e); + return CompletableFuture.<User>failedFuture(e); + } + }) + .collect(Collectors.toList()); + + // Wait for all to complete + CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])) + .thenRun(() -> { + logger.info("All users created successfully"); + System.out.println("Application started successfully!"); + }) + .exceptionally(throwable -> { + logger.error("Failed to initialize users", throwable); + System.err.println("Application startup failed!"); + return null; + }); + + } catch (Exception e) { + logger.error("Application startup failed", e); + System.exit(1); + } + } +}
\ No newline at end of file |
