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]

Reply via email to