I've got this working for pages and components, but it's probably a bit
different than what you want. I have a template table in my database
and I'm looking up content by a numeric PK rather than a name because I
have a requirement to let users version some templates. I'm also
leaving out my db access because it's somewhat domain-specific. This
assumes that all pages/components are specless and lets you specify a
backing class to associate with each template. You should be able hack
the page/jwc lookups using this as a model, though.
Credit goes to the tapestry wiki for how to write a delegate and
DynamicBlock for the trick with URL handlers to turn a string into a
hivemind resource.
-Steve
@Entity
@Table(name = "tapestry_components")
@SequenceGenerator(name = "SEQ", sequenceName = "tapestry_components_SEQ")
public class TapestryComponent {
private Integer id;
private String name;
private String template;
private Date creationDate = new Date();
private String backingClass;
@Column(name="backingClass")
public String getBackingClass() {
return backingClass;
}
public void setBackingClass(String backingClass) {
this.backingClass = backingClass;
}
public TapestryComponent() {}
public TapestryComponent(String name) {
setName(name);
}
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ")
public Integer getId() {
return id;
}
@Column(name = "name")
public String getName() {
return name;
}
public void setId(Integer id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
@Lob
@Column(name="template")
public String getTemplate() {
return template;
}
public void setTemplate(String template) {
this.template = template;
}
@Column(name="creation_date")
public Date getCreationDate() {
return creationDate;
}
public void setCreationDate(Date creationDate) {
this.creationDate = creationDate;
}
}
public class DatabasePageResolver implements
ISpecificationResolverDelegate {
public DatabasePageResolver() {}
public IComponentSpecification
findComponentSpecification(IRequestCycle cycle,
INamespace namespace, String name) {
return findSpecification(cycle, namespace, name, false);
}
public IComponentSpecification findPageSpecification(IRequestCycle
cycle, INamespace namespace, String name) {
return findSpecification(cycle, namespace, name, true);
}
private IComponentSpecification findSpecification(IRequestCycle
cycle, INamespace namespace, String name, boolean isPage) {
try {
Integer.valueOf(name);
} catch (NumberFormatException e) {
return null; // not a valid format
}
DatabasePageResource resource = new DatabasePageResource(name,
cycle.getEngine().getLocale());
if (!resource.exists()) {
return null;
}
Resource specResource = resource.getRelativeResource(name +
(isPage ? ".page" : ".jwc"));
IComponentSpecification specification = new
ComponentSpecification();
specification.setPageSpecification(isPage);
specification.setSpecificationLocation(specResource);
specification.setLocation(new LocationImpl(resource));
if (resource.getBackingClass() != null) {
specification.setComponentClassName(resource.getBackingClass());
}
return specification;
}
}
public class DatabasePageResource implements Resource {
private Locale locale;
private String componentName;
private TapestryComponent component;
public DatabasePageResource(String componentName, Locale locale) {
this.componentName = componentName;
this.locale = locale;
load();
}
public String getBackingClass() {
return component.getBackingClass();
}
private void load() {
try {
Integer componentId = Integer.valueOf(componentName);
component = // code omitted - use your own infrastructure to
read TapestryComponent object from the database here
} catch (NumberFormatException e) {
throw new IllegalArgumentException(componentName + " is
non-numeric and therefore not a valid component ID");
}
}
public Locale getLocale() {
return locale;
}
public Resource getLocalization(Locale arg0) {
return this;
}
public String getName() {
return componentName;
}
public String getPath() {
return componentName;
}
public Resource getRelativeResource(String resourceName) {
return new DatabasePageResource(componentName, locale);
}
public boolean exists() {
return component != null;
}
public URL getResourceURL() {
try {
return new URL(null, "database:///" + componentName, new
DatabaseURLStreamHandler(component.getTemplate()));
} catch (MalformedURLException e) {
// no-op - fall through to next page locator
return null;
}
}
public String toString() {
return "DatabasePageResource (ID=" + getName() + ")";
}
static class DatabaseURLConnection extends URLConnection {
private String template;
public DatabaseURLConnection(URL url, String template) {
super(url);
this.template = template;
}
public boolean exists() {
return template != null;
}
public void connect() {}
public boolean getAllowuserInteraction() {
return false;
}
public Object getContent() {
return template;
}
public InputStream getInputStream() {
if (template == null) {
return null;
}
return new ByteArrayInputStream(template.getBytes());
}
public String getString() {
return template;
}
}
static class DatabaseURLStreamHandler extends URLStreamHandler {
private String template;
DatabaseURLStreamHandler(String template) {
this.template = template;
}
public URLConnection openConnection(URL url) {
return new DatabaseURLConnection(url, template);
}
}
}
hivemodule entry:
<implementation service-id="tapestry.page.SpecificationResolverDelegate" >
<create-instance
class="com.vms.infrastructure.tapestry.DatabasePageResolver" />
</implementation>
Tapestry User List wrote:
IComponentSpecification spec = new ComponentSpecification();
spec.setComponentClassName(CommonPage.class.getName());
Resource componentResource = ??? how to instanciate a resource and
fill it
with a String retrieved from a database ???
spec.setSpecificationLocation(componentResource);
AssetSpecification template = new AssetSpecification();
??? how to fill the asset with a String retrieved from a database ???
template.setLocation(new
DescribedLocation(spec.getSpecificationLocation(),
""));
spec.addAsset("$template", template);
Any idea ?
D.
2006/12/1, Tapestry User List <[EMAIL PROTECTED]>:
Hi,
I would like retrieve a tapestry specification definition (.page) and
the
template (.html) from a database.
For doing that, I create a class that implements
ISpecificationResolverDelegate .
The method findPageSpecification must return a
IComponentSpecification. So
I instanciate a ComponentSpecification object.
The problem is: how can I fill my componentSpecification object with the
.page content (xml) and .html content retrieved from a database ?
Thank you very much,
D.
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]