PlaywrightHtmlSource.java
package net.sasasin.sreader.service.extraction.browser;
import java.net.URI;
import java.util.Objects;
import net.sasasin.sreader.config.FeedReaderProperties;
import org.springframework.context.SmartLifecycle;
import org.springframework.stereotype.Service;
/**
* Public facade for Playwright page rendering.
*
* <p>Exposes standard single-page render and short-lived standard AutoPagerize sessions. All public
* render/start/stop operations are synchronized on this instance so Playwright operations and
* resource teardown never interleave.
*/
@Service
public class PlaywrightHtmlSource implements SmartLifecycle {
private final FeedReaderProperties.Playwright settings;
private final PlaywrightResourceLifecycle lifecycle;
private final StandardPlaywrightPageRenderer standardRenderer;
PlaywrightHtmlSource(
FeedReaderProperties properties,
PlaywrightResourceLifecycle lifecycle,
StandardPlaywrightPageRenderer standardRenderer) {
this.settings = Objects.requireNonNull(properties, "properties must not be null").playwright();
this.lifecycle = Objects.requireNonNull(lifecycle, "lifecycle must not be null");
this.standardRenderer =
Objects.requireNonNull(standardRenderer, "standardRenderer must not be null");
}
public synchronized String render(URI uri) {
return renderPage(uri).html();
}
public synchronized RenderedPage renderPage(URI uri) {
Objects.requireNonNull(uri, "uri must not be null");
if (!settings.enabled()) {
throw new IllegalStateException("Playwright full text extraction is disabled");
}
return standardRenderer.render(uri);
}
/**
* Runs {@code work} against one short-lived standard BrowserContext/Page session while holding
* this facade's monitor for the entire pagination chain. Does not load extensions or persistent
* profiles.
*/
public synchronized <T> T withStandardSession(PlaywrightSessionWork<T> work) {
Objects.requireNonNull(work, "work must not be null");
if (!settings.enabled()) {
throw new IllegalStateException("Playwright full text extraction is disabled");
}
return standardRenderer.withSession(work);
}
@Override
public synchronized void start() {
lifecycle.start();
}
@Override
public synchronized void stop() {
lifecycle.stop();
}
@Override
public boolean isRunning() {
return lifecycle.isRunning();
}
@Override
public boolean isAutoStartup() {
return false;
}
}