Functional Scope (In-Scope)
- Hierarchical Parent-Child Folder Tree: Represents multi-level directories uniformly using child and parent relationship matrices.
- O(1) Tag-Based Index Intersect: O(1) query index enabling efficient multi-tag "AND" search querying without full repository scans.
- Rich EXIF Media Metadata Store: Safely parses and indexes file size, layout constraints, spatial coordinates, and hardware camera specifications.
- HMAC Cryptographic Shared Links: Encodes token payload parameters with expirations directly, validated statelessly via signature checking.
Explicit Boundaries (Out-of-Scope)
- Concrete Blob Transcoding Engines: Omits real-time video/image compression algorithms, dynamic resolution resizing, and chunk loaders.
- Network-level CDN and S3 integrations: Simulates local file path identifiers instead of implementing actual S3 API adapters or cloud bucket uploaders.
Production reference implementations demonstrating nested folders, O(1) multi-tag queries, and stateless HMAC links in Java and Python:
// ─── JAVA BLUEPRINT ──────────────────────────────────────────────────────────
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.stream.Collectors;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
class ExifMetadata {
private final long fileSizeBytes;
private final int widthPixels;
private final int heightPixels;
private final String cameraModel;
private final double gpsLatitude;
private final double gpsLongitude;
public ExifMetadata(long fileSizeBytes, int widthPixels, int heightPixels, String cameraModel, double gpsLatitude, double gpsLongitude) {
this.fileSizeBytes = fileSizeBytes;
this.widthPixels = widthPixels;
this.heightPixels = heightPixels;
this.cameraModel = cameraModel;
this.gpsLatitude = gpsLatitude;
this.gpsLongitude = gpsLongitude;
}
public long getFileSizeBytes() { return fileSizeBytes; }
public int getWidthPixels() { return widthPixels; }
public int getHeightPixels() { return heightPixels; }
public String getCameraModel() { return cameraModel; }
public double getGpsLatitude() { return gpsLatitude; }
public double getGpsLongitude() { return gpsLongitude; }
}
class Image {
private final String id;
private final String filename;
private final String filePath;
private final long uploadTimeMs;
private final Set<String> tags;
private final ExifMetadata exifMetadata;
private final String folderId;
public Image(String id, String filename, String filePath, long uploadTimeMs, Set<String> tags, ExifMetadata exifMetadata, String folderId) {
this.id = id;
this.filename = filename;
this.filePath = filePath;
this.uploadTimeMs = uploadTimeMs;
this.tags = new HashSet<>(tags);
this.exifMetadata = exifMetadata;
this.folderId = folderId;
}
public String getId() { return id; }
public String getFilename() { return filename; }
public String getFilePath() { return filePath; }
public long getUploadTimeMs() { return uploadTimeMs; }
public Set<String> getTags() { return Collections.unmodifiableSet(tags); }
public ExifMetadata getExifMetadata() { return exifMetadata; }
public String getFolderId() { return folderId; }
}
class Folder {
private final String id;
private final String name;
private final String parentId; // null if Root
private final List<String> subfolderIds;
private final List<String> imageIds;
public Folder(String id, String name, String parentId) {
this.id = id;
this.name = name;
this.parentId = parentId;
this.subfolderIds = new CopyOnWriteArrayList<>();
this.imageIds = new CopyOnWriteArrayList<>();
}
public String getId() { return id; }
public String getName() { return name; }
public String getParentId() { return parentId; }
public List<String> getSubfolderIds() { return subfolderIds; }
public List<String> getImageIds() { return imageIds; }
public void addSubfolder(String folderId) {
subfolderIds.add(folderId);
}
public void addImage(String imageId) {
imageIds.add(imageId);
}
public void removeImage(String imageId) {
imageIds.remove(imageId);
}
}
class GalleryService {
private final Map<String, Folder> folders = new HashMap<>();
private final Map<String, Image> images = new HashMap<>();
private final Map<String, Set<String>> tagIndex = new HashMap<>();
private final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
private final String secretKey = "SuperSecretHMACGalleryKey";
private static final String ROOT_FOLDER_ID = "ROOT";
public GalleryService() {
folders.put(ROOT_FOLDER_ID, new Folder(ROOT_FOLDER_ID, "Root", null));
}
public Folder createFolder(String name, String parentId) {
String actualParent = (parentId == null) ? ROOT_FOLDER_ID : parentId;
rwLock.writeLock().lock();
try {
Folder parent = folders.get(actualParent);
if (parent == null) {
throw new IllegalArgumentException("Parent folder does not exist.");
}
String folderId = UUID.randomUUID().toString();
Folder newFolder = new Folder(folderId, name, actualParent);
folders.put(folderId, newFolder);
parent.addSubfolder(folderId);
return newFolder;
} finally {
rwLock.writeLock().unlock();
}
}
public Image uploadImage(String filename, String filePath, Set<String> tags, ExifMetadata exif, String folderId) {
String actualFolder = (folderId == null) ? ROOT_FOLDER_ID : folderId;
rwLock.writeLock().lock();
try {
Folder target = folders.get(actualFolder);
if (target == null) {
throw new IllegalArgumentException("Target folder does not exist.");
}
String imageId = UUID.randomUUID().toString();
Image newImage = new Image(imageId, filename, filePath, System.currentTimeMillis(), tags, exif, actualFolder);
images.put(imageId, newImage);
target.addImage(imageId);
// Populate Tag Index O(1)
for (String tag : tags) {
tagIndex.computeIfAbsent(tag.toLowerCase(), k -> new HashSet<>()).add(imageId);
}
return newImage;
} finally {
rwLock.writeLock().unlock();
}
}
public List<Image> searchImagesByTags(Set<String> queryTags) {
if (queryTags == null || queryTags.isEmpty()) {
return Collections.emptyList();
}
rwLock.readLock().lock();
try {
Set<String> intersectedIds = null;
for (String tag : queryTags) {
Set<String> matches = tagIndex.get(tag.toLowerCase());
if (matches == null || matches.isEmpty()) {
return Collections.emptyList(); // AND constraint fails
}
if (intersectedIds == null) {
intersectedIds = new HashSet<>(matches);
} else {
intersectedIds.retainAll(matches);
}
}
if (intersectedIds == null || intersectedIds.isEmpty()) {
return Collections.emptyList();
}
return intersectedIds.stream()
.map(images::get)
.sorted(Comparator.comparingLong(Image::getUploadTimeMs).reversed())
.collect(Collectors.toList());
} finally {
rwLock.readLock().unlock();
}
}
public String generateShareLink(String albumId, long ttlSeconds) {
rwLock.readLock().lock();
try {
if (!folders.containsKey(albumId)) {
throw new IllegalArgumentException("Target album/folder does not exist.");
}
} finally {
rwLock.readLock().unlock();
}
long expiryTimeMs = System.currentTimeMillis() + (ttlSeconds * 1000);
String payload = albumId + ":" + expiryTimeMs;
String signature = generateHMAC(payload);
return "https://gallery.app/shared?albumId=" + albumId + "&expires=" + expiryTimeMs + "&sig=" + signature;
}
public boolean validateShareLink(String albumId, long expiryTimeMs, String signature) {
if (System.currentTimeMillis() > expiryTimeMs) {
return false; // Link expired
}
String payload = albumId + ":" + expiryTimeMs;
String expectedSignature = generateHMAC(payload);
return constantTimeEquals(expectedSignature, signature);
}
public Folder getFolderContents(String folderId) {
rwLock.readLock().lock();
try {
return folders.get(folderId);
} finally {
rwLock.readLock().unlock();
}
}
public Image getImage(String imageId) {
rwLock.readLock().lock();
try {
return images.get(imageId);
} finally {
rwLock.readLock().unlock();
}
}
private String generateHMAC(String data) {
try {
Mac sha256HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
sha256HMAC.init(secretKeySpec);
byte[] hash = sha256HMAC.doFinal(data.getBytes(StandardCharsets.UTF_8));
StringBuilder hexString = new StringBuilder();
for (byte b : hash) {
String hex = Integer.toHexString(0xff & b);
if (hex.length() == 1) hexString.append('0');
hexString.append(hex);
}
return hexString.toString();
} catch (NoSuchAlgorithmException | InvalidKeyException e) {
throw new RuntimeException("HMAC computation failed", e);
}
}
private boolean constantTimeEquals(String a, String b) {
if (a == null || b == null) return false;
if (a.length() != b.length()) return false;
int result = 0;
for (int i = 0; i < a.length(); i++) {
result |= a.charAt(i) ^ b.charAt(i);
}
return result == 0;
}
}
public class Main {
public static void main(String[] args) throws Exception {
System.out.println("=== JAVA IMAGE GALLERY DEMO ===");
GalleryService service = new GalleryService();
// 1. Create album folders
Folder vacationAlbum = service.createFolder("Vacation 2026", null);
Folder subFolderPhotos = service.createFolder("Scenery", vacationAlbum.getId());
System.out.println("Created folder hierarchy structure.");
// 2. Upload images with EXIF metadata
ExifMetadata exif1 = new ExifMetadata(5420000L, 4032, 3024, "iPhone 15 Pro", 37.7749, -122.4194);
Image img1 = service.uploadImage("sunset.png", "/vacation/scenery/sunset.png",
new HashSet<>(Arrays.asList("nature", "sunset", "scenery")), exif1, subFolderPhotos.getId());
System.out.println("Uploaded Sunset Photo to scenery album: " + img1.getId());
ExifMetadata exif2 = new ExifMetadata(2150000L, 2048, 1536, "Canon EOS", 34.0522, -118.2437);
Image img2 = service.uploadImage("mountains.jpg", "/vacation/scenery/mountains.jpg",
new HashSet<>(Arrays.asList("nature", "mountain", "scenery")), exif2, subFolderPhotos.getId());
System.out.println("Uploaded Mountains Photo to scenery album: " + img2.getId());
// 3. Search photos via Multi-Tag AND intersection lookup
Set<String> searchTags = new HashSet<>(Arrays.asList("nature", "scenery"));
List<Image> searchResults = service.searchImagesByTags(searchTags);
System.out.println("Tag search for [nature, scenery] found " + searchResults.size() + " matches:");
for (Image img : searchResults) {
System.out.println(" - " + img.getFilename() + " (Camera: " + img.getExifMetadata().getCameraModel() + ")");
}
// 4. Shared stateful link generation with secure HMAC validation
String shareLink = service.generateShareLink(vacationAlbum.getId(), 2); // 2-second TTL expiration
System.out.println("Generated secure stateless share link:\n " + shareLink);
// Parse query params to validate link
String albumIdParam = vacationAlbum.getId();
long expiresParam = System.currentTimeMillis() + 2000;
String sigParam = shareLink.substring(shareLink.lastIndexOf("sig=") + 4);
boolean isValidImmediate = service.validateShareLink(albumIdParam, expiresParam, sigParam);
System.out.println("Validation check immediately: " + (isValidImmediate ? "Valid Access" : "Access Denied"));
System.out.println("Sleeping 2.5 seconds to force HMAC token expiration...");
Thread.sleep(2500);
boolean isValidPostSleep = service.validateShareLink(albumIdParam, expiresParam, sigParam);
System.out.println("Validation check after expiration: " + (isValidPostSleep ? "Valid Access" : "Access Denied"));
System.out.println("=== END OF JAVA DEMO ===");
}
}