Thank you Steve. That is exactly what I were looking for.

D.

2006/12/2, Steve Shucker <[EMAIL PROTECTED]>:

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