Start der Entwicklung für ContentType Survey

Dieser CT basiert - zumindest am Anfang - zu großen Teilen auf simplesurvey. Das simplesurvey aber als Applikation programmiert wurde, kann man es nicht innerhalb des CMS verwenden. Daher wird hier die Grundfunktion von simplesurvey übernommen und so geändert, daß es einen CT Survey anlegt, der dann wie alle anderen CTs verwendet werden kann.

Weiterführende Funktionen von simplesurvey - insb. die Quizfunktion mit abspeichern von korrekten Antworten und einer Punktevergabe - können dann als abgeleitete CT erzeugt werden.

Der Plan sieht zur Zeit so aus:

 * CT Survey verwendet ein FormSectionItem, um das Umfrageformular zu erzeugen
 * Die Antworten werden wie in simplesurvey in 2 Tabellen gespeichert: ct_surveys_responses und ct_survey_answers. Jedes Ausfüllen eines Fragebogens erzeugt einen Eintrag in ct_surveys_responses, welcher wiederum eine Anzahl an ct_surveys_answers verwaltet, die die Antworten für die einzelnen Fragen beinhalten
 * Die Verarbeitung der Daten erfolgt - analog zu simplesurvey und formbuilder - mit einem FormProcessListener

Dieser CT soll auch die grundlegenden Antwortabfragen zur Verfügung stellen, wie

 * alle Antworten zu einer Umfrage
 * alle Antworten eines Users (?)
 * Anworten eines Users auf eine bestimmte Umfrage

und eine öffentliche Seite für das Ergebnis bereitstellen.

git-svn-id: https://svn.libreccm.org/ccm/trunk@349 8810af33-2d31-482b-a856-94f89814c4df
master
quasi 2010-02-18 09:18:14 +00:00
parent 9b1c5313a7
commit 1fd85e0a1a
23 changed files with 1973 additions and 0 deletions

View File

@ -0,0 +1 @@
build

View File

@ -0,0 +1,26 @@
<?xml version="1.0"?>
<ccm:application xmlns:ccm="http://ccm.redhat.com/ccm-project"
name="ccm-cms-types-survey"
prettyName="Red Hat CCM Content Types"
version="6.6.0"
release="1"
webapp="ROOT">
<ccm:dependencies>
<ccm:requires name="ccm-core" version="6.6.0" relation="ge"/>
<ccm:requires name="ccm-cms" version="6.6.0" relation="ge"/>
</ccm:dependencies>
<ccm:directories>
<ccm:directory name="pdl"/>
<ccm:directory name="sql"/>
<ccm:directory name="src"/>
</ccm:directories>
<ccm:contacts>
<ccm:contact uri="http://www.redhat.com/software/rhea" type="website"/>
<ccm:contact uri="mailto:rhea@redhat.com" type="support"/>
</ccm:contacts>
<ccm:description>
The Survey Content Type for the Red Hat CCM CMS. In contrast to simplesurvey
application this one is integrated into the cms. So the surveys will be content
items and as such will have all the features of a content item.
</ccm:description>
</ccm:application>

View File

@ -0,0 +1,478 @@
model com.arsdigita.cms.contenttypes;
import com.arsdigita.formbuilder.*;
object type Survey extends ContentPage {
component FormSection[1..1] formSection = join ct_surveys.form_id
to bebop_form_sections.form_section_id;
// Date[0..1] startDate = ct_surveys.start_date DATE;
// Date[0..1] endDate = ct_surveys.end_date DATE;
Boolean[0..1] responsesPublic = ct_surveys.responses_public CHAR(1);
reference key ( ct_surveys.survey_id );
}
object type SurveyResponse extends ContentItem {
Survey[1..1] survey = join ct_surveys_responses.survey_id
to ct_surveys.survey_id;
User[1..1] user = join ct_surveys_responses.user_id
to users.user_id;
Date[1..1] entryDate = ct_surveys_responses.entry_date DATE;
component Answer[1..n] answers = join ct_surveys_responses.response_id
to ct_surveys_answers.response_id;
// XXX hack to allow us to filter a data query
BigDecimal[1..1] surveyID = ct_surveys_responses.survey_id INTEGER;
BigDecimal[1..1] userID = ct_surveys_responses.user_id INTEGER;
reference key (ct_surveys_responses.response_id);
}
object type SurveyAnswer extends ContentItem{
BigDecimal[1..1] id = ct_surveys_answers.answer_id INTEGER;
Component[1..1] label = join ct_surveys_answers.label_id
to bebop_components.component_id;
Component[1..1] widget = join ct_surveys_answers.widget_id
to bebop_components.component_id;
String[0..1] value = ct_surveys_answers.value VARCHAR(4000);
object key (id);
}
/* From simplesurvey...
query GetAnswersForResponse {
BigDecimal answerID;
String attributeString;
String answerValue;
do {
select ss_answers.answer_id,
ss_answers.response_id,
ss_answers.value,
bebop_components.attribute_string
from ss_answers, bebop_components
where ss_answers.response_id = :responseID
and ss_answers.label_id = bebop_components.component_id
order by ss_answers.response_id, ss_answers.answer_id
} map {
answerID = ss_answers.answer_id;
attributeString = bebop_components.attribute_string;
answerValue = ss_answers.value;
}
}
query GetFormLabels {
BigDecimal labelID;
String attributeString;
do {
select bebop_components.component_id,
bebop_components.attribute_string
from bebop_component_hierarchy, acs_objects, bebop_components, ss_surveys
where bebop_component_hierarchy.container_id = ss_surveys.form_id
and ss_surveys.survey_id = :surveyID
and bebop_component_hierarchy.component_id =
acs_objects.object_id
and acs_objects.default_domain_class = 'com.arsdigita.formbuilder.WidgetLabel'
and bebop_components.component_id = bebop_component_hierarchy.component_id
order by bebop_components.component_id
} map {
labelID = bebop_components.component_id;
attributeString = bebop_components.attribute_string;
}
}
query GetAnswersToQuestion {
BigDecimal answerID;
String answerValue;
do {
select ss_answers.answer_id,
ss_answers.value
from ss_answers, ss_responses
where ss_answers.response_id = ss_responses.response_id
and ss_answers.label_id = :labelID
and ss_responses.entry_date > :startDate
and ss_responses.entry_date < :endDate
} map {
answerID = ss_answers.answer_id;
answerValue = ss_answers.value;
}
}
query getCorrectAnswerToQuestion {
// This returns one correct answer value corresponding to the question's label
String answerValue;
do {
select value from ss_correct_answers
where label_id = :labelID
} map {
answerValue = value;
}
}
query getCorrectAnswers {
// This returns all labels to one survey
String answerValue;
BigInteger widgetID;
String parameterName;
String parameterModel;
String domainClass;
do {
select sca.value,
bc.component_id as widget_id,
bw.parameter_name,
bw.parameter_model,
o.default_domain_class
from bebop_component_hierarchy bch,
bebop_components bc,
bebop_widgets bw,
ss_surveys s,
ss_correct_answers sca,
acs_objects o
where bch.container_id = s.form_id
and sca.widget_id = bch.component_id
and bc.component_id = bch.component_id
and bc.component_id = bw.widget_id
and bc.component_id = o.object_id
and s.survey_id = :surveyID
} map {
widgetID = widget_id;
answerValue = sca.value;
parameterName = bw.parameter_name;
parameterModel = bw.parameter_model;
domainClass = o.default_domain_class;
}
}
query correctAnswerExists {
Boolean answerExists;
do {
select 1 as answer_exists_p from ss_correct_answers
where label_id = :labelID and widget_id = :widgetID
} map {
answerExists = answer_exists_p;
}
}
data operation insertCorrectAnswer {
do {
insert into ss_correct_answers( label_id, widget_id, value )
values ( :labelID, :widgetID, :value )
}
}
data operation updateCorrectAnswer {
do {
update ss_correct_answers set value = :value
where label_id = :labelID and widget_id = :widgetID
}
}
data operation updateAnswerValue {
do {
update bebop_options set answer_value = :answerValue
where option_id = :optionID
}
}
query GetAllAnswers {
BigDecimal responseID;
BigDecimal labelID;
String answerValue;
do {
select ss_answers.value,
ss_answers.response_id,
ss_answers.label_id
from ss_answers
where ss_answers.response_id in (select response_id from ss_responses
where survey_id = :surveyID)
order by ss_answers.response_id, ss_answers.label_id
} map {
answerValue = ss_answers.value;
responseID = ss_answers.response_id;
labelID = ss_answers.label_id;
}
}
query GetWidgetClassAfterLabel {
String widgetClass;
do {
select acs_objects.default_domain_class
from bebop_component_hierarchy, acs_objects
where bebop_component_hierarchy.component_id = acs_objects.object_id
and bebop_component_hierarchy.container_id = (select container_id from bebop_component_hierarchy
where component_id = :labelID)
and bebop_component_hierarchy.order_number = (select order_number + 1 from
bebop_component_hierarchy where component_id = :labelID)
} map {
widgetClass = acs_objects.default_domain_class;
}
}
query GetOneAnswerQuestionStatistics {
String value;
BigDecimal numberOfAnswers;
do {
select count(ss_answers.answer_id) number_of_answers,
ss_answers.value
from ss_answers
where ss_answers.label_id = :labelID
group by ss_answers.value
} map {
value = ss_answers.value;
numberOfAnswers = number_of_answers;
}
}
query getAnswerOption {
String questionText;
String answerText;
BigDecimal answerValue;
BigDecimal optionID;
do {
select h2.component_id as option_id,
op.label as answer_text,
op.answer_value,
bc.attribute_string as question_text
from bebop_component_hierarchy h1,
bebop_component_hierarchy h2,
bebop_component_hierarchy h3,
bebop_components bc,
bebop_options op,
acs_objects o2
where h2.container_id = h1.component_id
and h2.component_id = op.option_id
and bc.component_id = h3.component_id
and o2.object_id = h3.component_id
and h3.order_number = h1.order_number - 1
and h3.container_id = h1.container_id
and h2.component_id = op.option_id
and op.option_id = :optionID
and o2.default_domain_class = 'com.arsdigita.formbuilder.WidgetLabel'
} map {
optionID = option_id;
answerValue = answer_value;
questionText = question_text;
answerText = answer_text;
}
}
query getSurveyStatistics {
BigDecimal score;
BigDecimal surveyNumber;
BigDecimal surveyPercentage;
do {
select score,
survey_number,
round((survey_number/total)*100) as survey_percentage
from ( select r1.score,
count(*) survey_number,
r2.total
from ss_responses r1,
(select count(*) as total from ss_responses r3
where r3.survey_id = :surveyID) r2
where r1.survey_id = :surveyID
group by r1.score, r2.total) s
} map {
surveyNumber = survey_number;
score = score;
surveyPercentage = survey_percentage;
}
}
query GetTotalNumberOfAnswers {
BigDecimal numberOfAnswers;
do {
select count(*) number_of_answers
from ss_answers where label_id = :labelID
} map {
numberOfAnswers = number_of_answers;
}
}
query getAnswerOptions {
// Returns all singleselect/select multiple questions with one row per possible answer
// for the selected survey. Yes, we are assuming that the label is always directly before the widget on the form.
String questionText;
String answerText;
BigDecimal optionID;
BigDecimal labelID;
BigDecimal widgetID;
BigDecimal answerValue;
do {
select h1.component_id as widget_id,
h2.component_id as option_id,
bc.attribute_string as label_text,
bc.component_id as label_id,
op.label as option_text,
op.answer_value
from bebop_component_hierarchy h1,
bebop_component_hierarchy h2,
bebop_component_hierarchy h3,
bebop_options op,
bebop_components bc,
ss_surveys s,
acs_objects o2
where h2.container_id = h1.component_id
and h1.container_id = s.form_id
and bc.component_id = h3.component_id
and o2.object_id = h3.component_id
and h2.component_id = op.option_id
and h3.order_number = h1.order_number - 1
and h3.container_id = h1.container_id
and o2.default_domain_class = 'com.arsdigita.formbuilder.WidgetLabel' and s.survey_id = :surveyID
order by widget_id
} map {
widgetID = widget_id;
optionID = option_id;
questionText = label_text;
answerText = option_text;
labelID = label_id;
answerValue = answer_value;
}
}
data operation saveScore {
// Saves the score of the completed survey (only relevant for knowledge test surveys)
do {
update ss_responses set score =(
select count(*) from
ss_answers a,
ss_correct_answers ca
where a.widget_id = ca.widget_id
and a.value = ca.value
and a.response_id = :responseID
) where response_id = :responseID
}
}
data operation saveAssessmentScore {
// Saves the score of the completed survey (only relevant for personal assessment surveys)
do {
update ss_responses set score =
(select s.sum_points/t.total
from (select count(*) as total from ss_answers where response_id=:responseID) t,
(select sum(a.value) as sum_points
from bebop_options bo,
ss_surveys s,
ss_answers a,
bebop_component_hierarchy h1,
bebop_component_hierarchy h2
where s.form_id = h1.container_id
and h2.container_id = h1.component_id
and h2.component_id = bo.option_id
and bo.label = a.value
and a.response_id = :responseID) s)
where response_id = :responseID
}
}
query getResponseResults{
// Returns the user's answer vs the correct answer for a survey response of a knowledge test survey
BigDecimal questionNumber;
BigDecimal answerID;
String userAnswer;
String correctAnswer;
do {
select rownum as question_number,
a.answer_id,
a.value as user_answer,
ca.value as correct_answer
from ss_answers a,
ss_correct_answers ca
where a.widget_id(+) = ca.widget_id
and a.response_id = :responseID
order by a.widget_id
} map {
questionNumber = question_number;
answerID = a.answer_id;
userAnswer = a.user_answer;
correctAnswer = ca.correct_answer;
}
}
query getAssessmentResults {
// Returns the score of a user based on a personal assessment kind of survey (i.e. average answer option value)
BigDecimal answerCount; // The number of answers for which the user received this point value
BigDecimal answerValue; // THe point value for this answer
do { select count(*) as answer_count,
bo.answer_value
from bebop_options bo,
ss_surveys s,
ss_answers a,
bebop_component_hierarchy h1,
bebop_component_hierarchy h2
where s.form_id = h1.container_id
and h2.container_id = h1.component_id
and h2.component_id = bo.option_id
and bo.label = a.value
and a.response_id = :responseID
group by bo.answer_value
} map {
answerCount = answer_count;
answerValue = answer_value;
}
}
query getUserScore {
// Returns the user's score given a responseID for a knowledge test kind of survey
BigDecimal userScore;
BigDecimal maxScore;
do { select max(r.score) as user_score,
count(value) as max_score
from ss_responses r,
ss_correct_answers sca,
bebop_component_hierarchy bch,
bebop_components bc,
bebop_widgets bw,
ss_surveys s
where bch.container_id = s.form_id
and sca.widget_id = bch.component_id
and bc.component_id = bch.component_id
and bc.component_id = bw.widget_id
and s.survey_id = r.survey_id
and r.response_id = :responseID
} map {
userScore = user_score;
maxScore = max_score;
}
}
query questionsAnswered {
Boolean questionsAnswered;
do {
select decode(count(*),0,0,1) as questions_answered_p
from ss_answers a
where a.response_id = :responseID
} map {
questionsAnswered = questions_answered_p;
}
}
query getAllUsersScore {
// Returns the number of users that achieved each score for this
// particular survey
BigDecimal userCount;
BigDecimal surveyScore;
do { select count(response_id) as user_count, r.score
from ss_responses r
where r.survey_id = :surveyID
group by score
} map {
userCount = user_count;
surveyScore = r.score;
}
}
*/

View File

@ -0,0 +1,3 @@
begin;
\i ddl/postgres/create.sql
end;

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<ctd:content-types xmlns:ctd="http://xmlns.redhat.com/cms/content-types"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.redhat.com/cms/content-types content-types.xsd">
<ctd:content-type
label="Survey"
description="A survey type"
objectType="com.arsdigita.cms.contenttypes.Survey"
classname="com.arsdigita.cms.contenttypes.Survey">
<ctd:authoring-kit
createComponent="com.arsdigita.cms.ui.authoring.PageCreate">
<ctd:authoring-step
labelKey="cms.contenttypes.shared.basic_properties.title"
labelBundle="com.arsdigita.cms.ui.CMSResources"
descriptionKey="cms.contenttypes.shared.basic_properties.description"
descriptionBundle="com.arsdigita.cms.ui.CMSResources"
component="com.arsdigita.cms.contenttypes.ui.BaseContactPropertiesStep"
ordering="1"/>
<ctd:include href="/WEB-INF/content-types/assign-categories-step.xml"/>
</ctd:authoring-kit>
</ctd:content-type>
</ctd:content-types>

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<xrd:adapters
xmlns:xrd="http://xmlns.redhat.com/schemas/waf/xml-renderer-rules"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://rhea.redhat.com/schemas/waf/xml-renderer-rules xml-renderer-rules.xsd">
<!--
Extend adapter for ContentItemPanel to also output the associated objects.
The default properties for BaseContact are left as is and are inherited from ContentPage
-->
<xrd:context name="com.arsdigita.cms.dispatcher.SimpleXMLGenerator">
<xrd:adapter objectType="com.arsdigita.cms.contenttypes.Survey" extends="com.arsdigita.cms.ContentPage">
<xrd:attributes rule="exclude">
</xrd:attributes>
</xrd:adapter>
</xrd:context>
</xrd:adapters>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<registry>
<!-- nothing yet -->
<!--
<config class="com.arsdigita.cms.contenttypes.SurveyConfig" storage="ccm-cms-types-survey/survey.properties"/>
-->
</registry>

View File

@ -0,0 +1,18 @@
<load>
<requires>
<table name="inits"/>
<table name="acs_objects"/>
<table name="cms_items"/>
<initializer class="com.arsdigita.cms.Initializer"/>
</requires>
<provides>
<table name="ct_surveys"/>
<table name="ct_surveys_responses"/>
<table name="ct_surveys_answers"/>
<initializer class="com.arsdigita.cms.contenttypes.SurveyInitializer"/>
</provides>
<scripts>
<schema directory="ccm-cms-types-survey"/>
<data class="com.arsdigita.cms.contenttypes.SurveyLoader"/>
</scripts>
</load>

View File

@ -0,0 +1,206 @@
package com.arsdigita.cms.contenttypes;
import com.arsdigita.cms.ContentPage;
import com.arsdigita.cms.ContentType;
import com.arsdigita.persistence.DataObject;
import com.arsdigita.persistence.OID;
import com.arsdigita.persistence.SessionManager;
import com.arsdigita.persistence.DataCollection;
import java.math.BigDecimal;
import com.arsdigita.domain.DataObjectNotFoundException;
import com.arsdigita.formbuilder.PersistentForm;
import com.arsdigita.util.Assert;
/**
* A survey content type that represents a survey. This is
* based on the simplesurvey application.
*
* @author Sören Bernstein
*
*/
public class Survey extends ContentPage {
/** PDL property name for formSection */
public static final String FORM_SECTION = "formSection";
/** PDL property name for startDate */
// public static final String START_DATE = "startDate";
/** PDL property name for endDate */
// public static final String END_DATE = "endDate";
/** PDL property name for responsesPublic */
public static final String RESPONSES_PUBLIC = "responsesPublic";
/** Data object type for this domain object */
public static final String BASE_DATA_OBJECT_TYPE = "com.arsdigita.simplesurvey.Survey";
/**
* Default constructor. This creates a new (empty) Survey.
**/
public Survey() {
this(BASE_DATA_OBJECT_TYPE);
}
/**
* Constructor. The contained <code>DataObject</code> is retrieved
* from the persistent storage mechanism with an <code>OID</code>
* specified by <i>id</i> and
* <code>Address.BASE_DATA_OBJECT_TYPE</code>.
*
* @param id The <code>id</code> for the retrieved
* <code>DataObject</code>.
**/
public Survey(BigDecimal id) throws DataObjectNotFoundException {
this(new OID(BASE_DATA_OBJECT_TYPE, id));
}
/**
* Constructor. The contained <code>DataObject</code> is retrieved
* from the persistent storage mechanism with an <code>OID</code>
* specified by <i>id</i>.
*
* @param id The <code>OID</code> for the retrieved
* <code>DataObject</code>.
**/
public Survey(OID id) throws DataObjectNotFoundException {
super(id);
}
/**
* Constructor. Retrieves or creates a content item using the
* <code>DataObject</code> argument.
*
* @param obj The <code>DataObject</code> with which to create or
* load a content item
*/
public Survey(DataObject obj) {
super(obj);
}
/**
* Constructor. Creates a new content item using the given data
* object type. Such items are created as draft versions.
*
* @param type The <code>String</code> data object type of the
* item to create
*/
public Survey(String type) {
super(type);
}
/**
* For new content items, sets the associated content type if it
* has not been already set.
*/
@Override
public void beforeSave() {
super.beforeSave();
Assert.exists(getContentType(), ContentType.class);
}
/* accessors *****************************************************/
public void setForm(PersistentForm persistentForm) {
set(FORM_SECTION, persistentForm);
}
public PersistentForm getForm() {
return new PersistentForm((DataObject) get(FORM_SECTION));
}
/*
public void setStartDate(Date startDate) {
set(START_DATE, startDate);
}
public Date getStartDate() {
return (Date)get(START_DATE);
}
public void setEndDate(Date endDate) {
set(END_DATE, endDate);
}
public Date getEndDate() {
return (Date)get(END_DATE);
}
*/
public boolean responsesArePublic() {
return ((Boolean) get(RESPONSES_PUBLIC)).booleanValue();
}
public void setResponsesPublic(Boolean responsesPublic) {
set(RESPONSES_PUBLIC, responsesPublic);
}
/* Class methods *********************************************************/
public static Survey retrieve(BigDecimal id)
throws DataObjectNotFoundException {
Survey survey = new Survey(id);
return survey;
}
public static Survey retrieve(DataObject obj) {
Survey survey = new Survey(obj);
return survey;
}
/*
public SurveyResponseCollection getResponses() {
return SurveyResponse.retrieveBySurvey(this);
}
public SurveyResponseCollection getUserResponses(User user) {
return SurveyResponse.retrieveBySurvey(this, user);
}
public boolean hasUserResponded(User user) {
SurveyResponseCollection responses = getUserResponses(user);
if (responses.next()) {
responses.close();
return true;
}
return false;
}
*/
/*
public DataQuery getLabelDataQuery() {
String queryName = "com.arsdigita.simplesurvey.GetFormLabels";
DataQuery dataQuery =
SessionManager.getSession().retrieveQuery(queryName);
dataQuery.setParameter("surveyID", getID());
return dataQuery;
}
public boolean isLive() {
Date currentDate = new Date();
return getStartDate().compareTo(currentDate) < 0 &&
getEndDate().compareTo(currentDate) > 0;
}
*/
/*
* Retrieves most recent survey that isn't completed
*/
public static Survey getMostRecentSurvey() {
DataCollection surveys = SessionManager.getSession().retrieve(BASE_DATA_OBJECT_TYPE);
surveys.addFilter("startDate <= sysdate and endDate > sysdate");
surveys.addOrder("startDate desc");
Survey survey = null;
if (surveys.next()) {
survey = new Survey(surveys.getDataObject());
}
surveys.close();
return survey;
}
}

View File

@ -0,0 +1,119 @@
package com.arsdigita.cms.contenttypes;
import com.arsdigita.cms.ContentItem;
import com.arsdigita.cms.ContentType;
import com.arsdigita.db.Sequences;
import com.arsdigita.domain.DataObjectNotFoundException;
import com.arsdigita.formbuilder.PersistentLabel;
import com.arsdigita.formbuilder.PersistentWidget;
import com.arsdigita.persistence.DataObject;
import com.arsdigita.persistence.OID;
import com.arsdigita.util.Assert;
import java.math.BigDecimal;
/**
* A SurveyAnswer object represents a response by a user to
* a survey at a certain point in time. A survey response consists
* of a collection of answers to questions in the survey.
*
* @author Sören Bernstein
*
* Based on simplesurvey application
*/
public class SurveyAnswer extends ContentItem {
/** PDL property name for id */
public static final String ID = "id";
/** PDL property name for label */
public static final String LABEL = "label";
/** PDL property name for widget */
public static final String WIDGET = "widget";
/** PDL property name for value */
public static final String VALUE = "value";
/** PDL property name for response */
public static final String RESPONSE = "response";
/** Data object type for this domain object */
public static final String BASE_DATA_OBJECT_TYPE = "com.arsdigita.cms.contenttypes.SurveyAnswer";
/**
* Default constructor. This creates a new (empty) Survey.
**/
public SurveyAnswer() {
this(BASE_DATA_OBJECT_TYPE);
}
/**
* Constructor. The contained <code>DataObject</code> is retrieved
* from the persistent storage mechanism with an <code>OID</code>
* specified by <i>id</i> and
* <code>Address.BASE_DATA_OBJECT_TYPE</code>.
*
* @param id The <code>id</code> for the retrieved
* <code>DataObject</code>.
**/
public SurveyAnswer(BigDecimal id) throws DataObjectNotFoundException {
this(new OID(BASE_DATA_OBJECT_TYPE, id));
}
/**
* Constructor. The contained <code>DataObject</code> is retrieved
* from the persistent storage mechanism with an <code>OID</code>
* specified by <i>id</i>.
*
* @param id The <code>OID</code> for the retrieved
* <code>DataObject</code>.
**/
public SurveyAnswer(OID oid) throws DataObjectNotFoundException {
super(oid);
}
/**
* Constructor. Retrieves or creates a content item using the
* <code>DataObject</code> argument.
*
* @param obj The <code>DataObject</code> with which to create or
* load a content item
*/
public SurveyAnswer(DataObject obj) {
super(obj);
}
/**
* Constructor. Creates a new content item using the given data
* object type. Such items are created as draft versions.
*
* @param type The <code>String</code> data object type of the
* item to create
*/
public SurveyAnswer(String type) {
super(type);
}
/* accessors *****************************************************/
public BigDecimal getID() {
return (BigDecimal) get(ID);
}
/* Class methods ********/
public static SurveyAnswer create(PersistentLabel label,
PersistentWidget widget,
String value) {
SurveyAnswer answer = new SurveyAnswer();
answer.setup(label, widget, value);
return answer;
}
protected void setup(PersistentLabel label,
PersistentWidget widget,
String value) {
try {
set(ID, Sequences.getNextValue("ss_answers_seq"));
} catch (java.sql.SQLException e) {
throw new com.arsdigita.util.UncheckedWrapperException(e);
}
set(LABEL, label);
set(WIDGET, widget);
set(VALUE, value);
}
}

View File

@ -0,0 +1,31 @@
package com.arsdigita.cms.contenttypes;
import org.apache.log4j.Logger;
/**
*
* @author Sören Bernstein;
*/
public class SurveyInitializer extends ContentTypeInitializer {
public final static String versionId =
"$Id: SurveyInitializer.java $" +
"$Author: quasi $" +
"$DateTime: 2010/02/18 $";
private static final Logger s_log = Logger.getLogger(SurveyInitializer.class);
public SurveyInitializer() {
super("ccm-cms-types-survey.pdl.mf",
Survey.BASE_DATA_OBJECT_TYPE);
}
public String[] getStylesheets() {
return new String[]{
"/static/content-types/com/arsdigita/cms/contenttypes/Survey.xsl"
};
}
public String getTraversalXML() {
return "/WEB-INF/traversal-adapters/com/arsdigita/cms/contenttypes/Survey.xml";
}
}

View File

@ -0,0 +1,23 @@
package com.arsdigita.cms.contenttypes;
import com.arsdigita.cms.contenttypes.AbstractContentTypeLoader;
/**
* Loader.
*
* @author Sören Bernstein
*/
public class SurveyLoader extends AbstractContentTypeLoader {
public final static String versionId =
"$Id: SurveyLoader.java $" +
"$Author: quasi $" +
"$DateTime: 2010/02/18 $";
private static final String[] TYPES = {
"/WEB-INF/content-types/com/arsdigita/cms/contenttypes/Survey.xml"
};
public String[] getTypes() {
return TYPES;
}
}

View File

@ -0,0 +1,58 @@
cms.contenttypes.ui.survey.ui.admin.and=and
cms.contenttypes.ui.survey.ui.admin.add_new_survey=Add new Survey
cms.contenttypes.ui.survey.ui.admin.add_new_poll=Add new Poll
cms.contenttypes.ui.survey.ui.admin.surveys=Surveys
cms.contenttypes.ui.survey.ui.admin.polls=Polls
cms.contenttypes.ui.survey.ui.admin.back_to_question_list=Back to question list
cms.contenttypes.ui.survey.ui.admin.question=Question:
cms.contenttypes.ui.survey.ui.admin.back_to_response_list=Back to response list
cms.contenttypes.ui.survey.ui.admin.name=Name:
cms.contenttypes.ui.survey.ui.admin.description=Description:
cms.contenttypes.ui.survey.ui.admin.start_date=Start Date:
cms.contenttypes.ui.survey.ui.admin.end_date=End Date:
cms.contenttypes.ui.survey.ui.admin.back_to_survey_list=Back to survey list
cms.contenttypes.ui.survey.ui.admin.questions_of_the_survey=Questions of the Survey
cms.contenttypes.ui.survey.ui.admin.responses_to_the_survey=Responses to the Survey
cms.contenttypes.ui.survey.ui.admin.export_response_data=Export Response Data
cms.contenttypes.ui.survey.ui.admin.administration=Administration
cms.contenttypes.ui.survey.ui.admin.active=active
cms.contenttypes.ui.survey.ui.admin.inactive=inactive
cms.contenttypes.ui.survey.ui.admin.view_responses=View Responses
cms.contenttypes.ui.survey.ui.admin.edit_controls=Edit controls
cms.contenttypes.ui.survey.ui.admin.edit_properties=Edit properties
cms.contenttypes.ui.survey.ui.admin.delete=Delete
cms.contenttypes.ui.survey.ui.admin.should_quiz_responses_be_public=Should responses be public?
cms.contenttypes.ui.survey.ui.admin.set_correct_answers=Set correct answers
cms.contenttypes.ui.survey.ui.admin.what_type_of_quiz_is_this= What type of quiz is this?
cms.contenttypes.ui.survey.ui.admin.knowledge_test_quiz=Knowledge Test
cms.contenttypes.ui.survey.ui.admin.personal_assessment_quiz=Personal Assessment
cms.contenttypes.ui.survey.ui.admin.question=Question
cms.contenttypes.ui.survey.ui.admin.answer=Answer
cms.contenttypes.ui.survey.ui.admin.edit_value=Edit Value
cms.contenttypes.ui.survey.ui.admin.current_value=Current Value
cms.contenttypes.ui.survey.ui.admin.submit=Submit
cms.contenttypes.ui.survey.ui.admin.done_editing=Done Editing
cms.contenttypes.ui.survey.ui.admin.set_answer_values=Set answer values
cms.contenttypes.ui.survey.ui.Yes=Yes
cms.contenttypes.ui.survey.ui.No=No
cms.contenttypes.ui.survey.ui.you_have_scored_out_of_a_possible=You have scored {0} out of a possible {1} point(s).
cms.contenttypes.ui.survey.ui.you_have_scored=You have scored
cms.contenttypes.ui.survey.ui.answers_worth=answer(s) worth
cms.contenttypes.ui.survey.ui.view_all_results= View public statistics
cms.contenttypes.ui.survey.ui.points=points
cms.contenttypes.ui.survey.ui.administer=Administer
cms.contenttypes.ui.survey.ui.active_surveys=Active Surveys
cms.contenttypes.ui.survey.ui.active_polls=Active Polls
cms.contenttypes.ui.survey.ui.simple_survey_index_page=Simple Survey Index Page
cms.contenttypes.ui.survey.ui.this_survey_is_not_currently_active=This survey is not currently active
cms.contenttypes.ui.survey.ui.you_have_already_completed_this_survey=You have already completed this survey
cms.contenttypes.ui.survey.ui.thankyou_for_completing_the_survey=Thank you for completing this survey!
cms.contenttypes.ui.survey.ui.question_number=Question Number
cms.contenttypes.ui.survey.ui.user_answer=User Answer
cms.contenttypes.ui.survey.ui.correct_answer=Correct Answer
cms.contenttypes.ui.survey.ui.score=Score
cms.contenttypes.ui.survey.ui.number_of_surveys=Number of Surveys
cms.contenttypes.ui.survey.ui.percentage=Surveys in percent

View File

@ -0,0 +1,59 @@
cms.contenttypes.ui.survey.ui.admin.and=und
cms.contenttypes.ui.survey.ui.admin.add_new_survey=Neue Umfrage hinzuf\u00FCgen
cms.contenttypes.ui.survey.ui.admin.surveys=Umfragens
cms.contenttypes.ui.survey.ui.admin.back_to_question_list=Zur\u00FCck zur Fragenliste
cms.contenttypes.ui.survey.ui.admin.question=Frage:
cms.contenttypes.ui.survey.ui.admin.back_to_response_list=Zur\u00FCck zur Antwortliste
cms.contenttypes.ui.survey.ui.admin.name=Name:
cms.contenttypes.ui.survey.ui.admin.description=Beschreibung:
cms.contenttypes.ui.survey.ui.admin.start_date=Startdatum:
cms.contenttypes.ui.survey.ui.admin.end_date=Enddatum:
cms.contenttypes.ui.survey.ui.admin.back_to_survey_list=Zur\u00FCck zur Umfrageliste
cms.contenttypes.ui.survey.ui.admin.questions_of_the_survey=Fragen der Umfrage
cms.contenttypes.ui.survey.ui.admin.responses_to_the_survey=Antworten der Umfrage
cms.contenttypes.ui.survey.ui.admin.export_response_data=Antworten exportieren
cms.contenttypes.ui.survey.ui.admin.administration=Administration
cms.contenttypes.ui.survey.ui.admin.active=aktiv
cms.contenttypes.ui.survey.ui.admin.inactive=inaktiv
cms.contenttypes.ui.survey.ui.admin.view_responses=Antworten ansehen
cms.contenttypes.ui.survey.ui.admin.edit_controls=Edit controls
cms.contenttypes.ui.survey.ui.admin.edit_properties=Eigenschaften bearbeiten
cms.contenttypes.ui.survey.ui.admin.delete=L\u00F6schen
cms.contenttypes.ui.survey.ui.admin.should_quiz_responses_be_public=Sollen die Antworten \u00F6ffentlich sein?
cms.contenttypes.ui.survey.ui.admin.question=Frage
cms.contenttypes.ui.survey.ui.admin.answer=Antwort
cms.contenttypes.ui.survey.ui.admin.edit_value=Wert bearbeiten
cms.contenttypes.ui.survey.ui.admin.current_value=Aktueller Wert
cms.contenttypes.ui.survey.ui.admin.submit=Absenden
cms.contenttypes.ui.survey.ui.admin.done_editing=Bearbeitung beenden
cms.contenttypes.ui.survey.ui.admin.set_answer_values=Antwortwert setzen
cms.contenttypes.ui.survey.ui.admin.set_correct_answers=Set correct answers
cms.contenttypes.ui.survey.ui.admin.what_type_of_quiz_is_this= What type of quiz is this?
cms.contenttypes.ui.survey.ui.admin.knowledge_test_quiz=Knowledge Test
cms.contenttypes.ui.survey.ui.admin.personal_assessment_quiz=Personal Assessment
cms.contenttypes.ui.survey.ui.you_have_scored_out_of_a_possible=You have scored {0} out of a possible {1} point(s).
cms.contenttypes.ui.survey.ui.you_have_scored=You have scored
cms.contenttypes.ui.survey.ui.answers_worth=answer(s) worth
cms.contenttypes.ui.survey.ui.Yes=Ja
cms.contenttypes.ui.survey.ui.No=Nein
cms.contenttypes.ui.survey.ui.view_all_results= View public statistics
cms.contenttypes.ui.survey.ui.points=points
cms.contenttypes.ui.survey.ui.administer=Administer
cms.contenttypes.ui.survey.ui.active_surveys=Active Surveys
cms.contenttypes.ui.survey.ui.active_polls=Active Polls
cms.contenttypes.ui.survey.ui.simple_survey_index_page=Simple Survey Index Page
cms.contenttypes.ui.survey.ui.this_survey_is_not_currently_active=This survey is not currently active
cms.contenttypes.ui.survey.ui.you_have_already_completed_this_survey=You have already completed this survey
cms.contenttypes.ui.survey.ui.thankyou_for_completing_the_survey=Thank you for completing this survey!
cms.contenttypes.ui.survey.ui.question_number=Question Number
cms.contenttypes.ui.survey.ui.user_answer=User Answer
cms.contenttypes.ui.survey.ui.correct_answer=Correct Answer
cms.contenttypes.ui.survey.ui.score=Score
cms.contenttypes.ui.survey.ui.number_of_surveys=Number of Surveys
cms.contenttypes.ui.survey.ui.percentage=Surveys in percent

View File

@ -0,0 +1,60 @@
cms.contenttypes.ui.survey.ui.admin.and=et
cms.contenttypes.ui.survey.ui.admin.add_new_survey=Ajouter un nouveau sondage
cms.contenttypes.ui.survey.ui.admin.add_new_poll=Ajouter un nouveau scrutin
cms.contenttypes.ui.survey.ui.admin.surveys=Sondages
cms.contenttypes.ui.survey.ui.admin.polls=Scrutins
cms.contenttypes.ui.survey.ui.admin.back_to_question_list=Retour \u00E0 la liste des questions
cms.contenttypes.ui.survey.ui.admin.question=Question:
cms.contenttypes.ui.survey.ui.admin.back_to_response_list=Retour \u00E0 la liste des r\u00E9ponses
cms.contenttypes.ui.survey.ui.admin.name=Titre:
cms.contenttypes.ui.survey.ui.admin.description=Description:
cms.contenttypes.ui.survey.ui.admin.start_date=Date de d\u00E9marrage:
cms.contenttypes.ui.survey.ui.admin.end_date=Date de fin:
cms.contenttypes.ui.survey.ui.admin.back_to_survey_list=Retour \u00E0 la liste des sondages
cms.contenttypes.ui.survey.ui.admin.questions_of_the_survey=Questions de l'enqu\u00EAte
cms.contenttypes.ui.survey.ui.admin.responses_to_the_survey=Responses de l'enqu\u00EAte
cms.contenttypes.ui.survey.ui.admin.export_response_data=Exporter les r\u00E9ponses
cms.contenttypes.ui.survey.ui.admin.administration=Administration
cms.contenttypes.ui.survey.ui.admin.active=actif
cms.contenttypes.ui.survey.ui.admin.inactive=inactif
cms.contenttypes.ui.survey.ui.admin.view_responses=Voir les r\u00E9ponses
cms.contenttypes.ui.survey.ui.admin.edit_controls=Modifier les contr\u00F4les
cms.contenttypes.ui.survey.ui.admin.edit_properties=Modifier les propri\u00E9t\u00E9s
cms.contenttypes.ui.survey.ui.admin.delete=Effacer
cms.contenttypes.ui.survey.ui.admin.should_quiz_responses_be_public=Est-e que les r\u00E9ponses sont public?
cms.contenttypes.ui.survey.ui.admin.set_correct_answers=Indiquer les bonnes r\u00E9ponses.
cms.contenttypes.ui.survey.ui.admin.what_type_of_quiz_is_this=Quel est le type de ce quiz?
cms.contenttypes.ui.survey.ui.admin.knowledge_test_quiz=Tests de connaissances
cms.contenttypes.ui.survey.ui.admin.personal_assessment_quiz=Evaluation personnelle
cms.contenttypes.ui.survey.ui.admin.question=Question
cms.contenttypes.ui.survey.ui.admin.answer=R\u00E9ponse
cms.contenttypes.ui.survey.ui.admin.edit_value=Modifier la valeur
cms.contenttypes.ui.survey.ui.admin.current_value=Valeur courante
cms.contenttypes.ui.survey.ui.admin.submit=Soumettre
cms.contenttypes.ui.survey.ui.admin.done_editing=Modifications effectu\u00E9es
cms.contenttypes.ui.survey.ui.admin.set_answer_values=Indiquer la valeur des r\u00E9ponses
cms.contenttypes.ui.survey.ui.Yes=oui
cms.contenttypes.ui.survey.ui.No=Non
cms.contenttypes.ui.survey.ui.you_have_scored_out_of_a_possible=Vous avez marqu\u00E9 {0} point(s) sur un total de {1}.
cms.contenttypes.ui.survey.ui.you_have_scored=Vous avez marqu\u00E9
cms.contenttypes.ui.survey.ui.answers_worth=answer(s) worth
cms.contenttypes.ui.survey.ui.view_all_results=Voir les statistiques publique
cms.contenttypes.ui.survey.ui.points=points
cms.contenttypes.ui.survey.ui.administer=Administrer
cms.contenttypes.ui.survey.ui.active_surveys=Enqu\u00EAtes actives
cms.contenttypes.ui.survey.ui.active_polls=Scrutins actifs
cms.contenttypes.ui.survey.ui.simple_survey_index_page=Sommaire des enqu\u00EAtes actives
cms.contenttypes.ui.survey.ui.this_survey_is_not_currently_active=Cette enqu\u00EAte n'est active actuellement
cms.contenttypes.ui.survey.ui.you_have_already_completed_this_survey=Vous avez d\u00E9j\u00E0 r\u00E9pondu \u00E0 cette enqu\u00EAte
cms.contenttypes.ui.survey.ui.thankyou_for_completing_the_survey=Merci d'avoir r\u00E9pondu \u00E0 cette enqu\u00EAte
cms.contenttypes.ui.survey.ui.question_number=Question Num\u00E9ro
cms.contenttypes.ui.survey.ui.user_answer=R\u00E9ponse de l'utilisateur
cms.contenttypes.ui.survey.ui.correct_answer=Bonne r\u00E9ponse
cms.contenttypes.ui.survey.ui.score=Score
cms.contenttypes.ui.survey.ui.number_of_surveys=Nombre d'enqu\u00EAtes
cms.contenttypes.ui.survey.ui.percentage=Pourcentages sur les enqu\u00EAtes
cms.contenttypes.ui.survey.ui.you_have_already_completed_this_survey=TRANSLATE THIS: You have already completed this survey (cms.contenttypes.ui.survey.ui.you_have_already_completed_this_survey)

View File

@ -0,0 +1,156 @@
package com.arsdigita.cms.contenttypes;
import com.arsdigita.cms.ContentItem;
import com.arsdigita.domain.DataObjectNotFoundException;
import com.arsdigita.formbuilder.PersistentLabel;
import com.arsdigita.formbuilder.PersistentWidget;
import com.arsdigita.kernel.User;
import com.arsdigita.persistence.DataObject;
import com.arsdigita.persistence.OID;
import com.arsdigita.simplesurvey.Survey;
import java.math.BigDecimal;
import java.util.Date;
/**
* A SurveyResponse object represents a response by a user to
* a survey at a certain point in time. A survey response consists
* of a collection of answers to questions in the survey.
*
* @author Sören Bernstein
*
* Based on simplesurvey application
*/
public class SurveyResponse extends ContentItem {
/** PDL property name for survey */
public static final String SURVEY = "survey";
/** PDL property name for user */
public static final String USER = "user";
/** PDL property name for entryDate */
public static final String ENTRY_DATE = "entryDate";
/** PDL property name for answers */
public static final String ANSWERS = "answers";
/** Data object type for this domain object */
public static final String BASE_DATA_OBJECT_TYPE = "com.arsdigita.cms.contenttypes.SurveyResponse";
/**
* Default constructor. This creates a new (empty) Survey.
**/
public SurveyResponse() {
this(BASE_DATA_OBJECT_TYPE);
}
/**
* Constructor. The contained <code>DataObject</code> is retrieved
* from the persistent storage mechanism with an <code>OID</code>
* specified by <i>id</i> and
* <code>Address.BASE_DATA_OBJECT_TYPE</code>.
*
* @param id The <code>id</code> for the retrieved
* <code>DataObject</code>.
**/
public SurveyResponse(BigDecimal id) throws DataObjectNotFoundException {
this(new OID(BASE_DATA_OBJECT_TYPE, id));
}
/**
* Constructor. The contained <code>DataObject</code> is retrieved
* from the persistent storage mechanism with an <code>OID</code>
* specified by <i>id</i>.
*
* @param id The <code>OID</code> for the retrieved
* <code>DataObject</code>.
**/
protected SurveyResponse(OID oid) throws DataObjectNotFoundException {
super(oid);
}
/**
* Constructor. Retrieves or creates a content item using the
* <code>DataObject</code> argument.
*
* @param obj The <code>DataObject</code> with which to create or
* load a content item
*/
public SurveyResponse(DataObject obj) {
super(obj);
}
/**
* Constructor. Creates a new content item using the given data
* object type. Such items are created as draft versions.
*
* @param type The <code>String</code> data object type of the
* item to create
*/
public SurveyResponse(String type) {
super(type);
}
/* accessors *****************************************************/
public void addAnswer(PersistentLabel label, PersistentWidget widget, String value) {
SurveyAnswer answer = SurveyAnswer.create(label, widget, value);
add(ANSWERS, answer);
}
public Date getEntryDate() {
return (Date) get(ENTRY_DATE);
}
/* Class methods **********************************************************/
public static SurveyResponse create(Survey survey, User user) {
SurveyResponse response = new SurveyResponse();
response.setup(survey, user);
return response;
}
protected void setup(Survey survey, User user) {
set(ENTRY_DATE, new Date());
// XXX hack - see pdl file
set(USER + "ID", user.getID());
set(SURVEY + "ID", survey.getID());
}
public static SurveyResponse retrieve(DataObject obj) {
return new SurveyResponse(obj);
}
/*
public static SurveyResponseCollection retrieveBySurvey(Survey survey) {
DataCollection responses =
SessionManager.getSession().retrieve(BASE_DATA_OBJECT_TYPE);
responses.addEqualsFilter(SURVEY + "ID",
survey.getID());
return new SurveyResponseCollection(responses);
}
public static SurveyResponseCollection retrieveBySurvey(Survey survey, User user) {
SurveyResponseCollection responses = retrieveBySurvey(survey);
responses.addEqualsFilter(USER + "ID",
user.getID());
return responses;
}
*/
public boolean questionsAnswered() {
// Returns true of questions have been answered on this response
BigDecimal responseID = this.getID();
// DataQuery dq = SessionManager.getSession().retrieveQuery("com.arsdigita.simplesurvey.questionsAnswered");
// dq.setParameter("responseID", responseID);
// dq.next();
// Boolean questionsAnswered = (Boolean) dq.get(QUESTIONS_ANSWERED);
// dq.close();
// return questionsAnswered.booleanValue();
// HACK: Brauche ich diese Funktion?
return true;
}
}

View File

@ -0,0 +1,237 @@
/*
* Copyright (C) 2002-2004 Red Hat Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package com.arsdigita.simplesurvey.ui;
import com.arsdigita.bebop.event.FormProcessListener;
import com.arsdigita.bebop.event.FormSectionEvent;
import com.arsdigita.formbuilder.PersistentComponent;
import com.arsdigita.formbuilder.PersistentForm;
import com.arsdigita.formbuilder.PersistentLabel;
import com.arsdigita.formbuilder.PersistentWidget;
import com.arsdigita.kernel.KernelHelper;
import com.arsdigita.domain.DataObjectNotFoundException;
import com.arsdigita.domain.DomainObjectFactory;
import com.arsdigita.persistence.OID;
import java.util.Map;
import java.util.HashMap;
import com.arsdigita.bebop.FormData;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.RequestLocal;
import com.arsdigita.simplesurvey.Survey;
import com.arsdigita.simplesurvey.Response;
import com.arsdigita.bebop.RequestLocal;
import com.arsdigita.simplesurvey.ui.Question;
import com.arsdigita.bebop.parameters.ParameterData;
import com.arsdigita.persistence.DataAssociationCursor;
import com.arsdigita.persistence.DataOperation;
import com.arsdigita.persistence.SessionManager;
import java.util.Iterator;
import com.arsdigita.formbuilder.util.FormBuilderUtil;
import com.arsdigita.kernel.User;
import java.math.BigDecimal;
import org.apache.log4j.Logger;
/**
* The process lister that processes a survey response entered by a user.
*
* @author <a href="mailto:pmarklun@arsdigita.com">Peter Marklund</a>
* @version $Id: SurveyProcessListener.java 759 2005-09-02 15:25:32Z sskracic $
*/
public class SurveyProcessListener
implements FormProcessListener {
public static final String SURVEY_ID_NAME = "__ss_survey_id__";
public static final String RESPONSE_ID = "__ss_response_id__";
public static final BigDecimal THE_PUBLIC_USER = new BigDecimal(-200);
private static final String KNOWLEDGE_TEST = "knowledge_test";
protected RequestLocal m_persistentForm = new RequestLocal();
private RequestLocal m_nameQuestionMap = new RequestLocal();
private RequestLocal m_response;
private static org.apache.log4j.Logger s_log =
Logger.getLogger(SurveyProcessListener.class.getName());
public SurveyProcessListener(RequestLocal response) {
m_response = response;
}
public SurveyProcessListener() {
m_response = null;
}
public void process(FormSectionEvent event) {
FormData formData = event.getFormData();
PageState ps = event.getPageState();
BigDecimal surveyID = (BigDecimal)formData.get(SURVEY_ID_NAME);
BigDecimal responseID = (BigDecimal)formData.get(RESPONSE_ID);
m_response.set(ps, responseID);
Survey survey = (Survey) FormBuilderUtil.instantiateObjectOneArg(Survey.class.getName(), surveyID);
Response response = null;
try {
response = (Response) DomainObjectFactory.newInstance( new OID(Response.class.getName(), responseID));
} catch (DataObjectNotFoundException ex) {
// s_log.warn("Can't create this object" + responseID);
}
//Let's not save the data twice in the case of a double-click
if ( response.questionsAnswered() ) {
return;
}
m_persistentForm.set(ps, survey.getForm());
// Get the responding user
User user = KernelHelper.getCurrentUser(ps.getRequest());
// Use the generic user "The Public" if the user is not registered
if ( user == null) {
try {
user = User.retrieve(THE_PUBLIC_USER);
} catch ( DataObjectNotFoundException e ) {
s_log.error("Public User does not exist.");
}
}
// Iterate over the widget parameters and insert the answers to the survey response
Iterator parameterIter = formData.getParameters().iterator();
while (parameterIter.hasNext()) {
s_log.warn("Found some formData");
ParameterData parameterData = (ParameterData)parameterIter.next();
String parameterName = (String)parameterData.getName();
Object parameterValue = parameterData.getValue();
if (parameterValue instanceof java.lang.String[]) {
// This is a multi-answer question - iterate over the
// answer values and add them one by one
String[] valueArray = (String[])parameterValue;
for (int i = 0; i < valueArray.length; ++i) {
addAnswer(response, ps, valueArray[i], parameterName);
}
} else {
// Single answer question
addAnswer(response, ps, parameterValue, parameterName);
}
}
// Save the survey response to the database
response.save();
saveScore(survey, response);
}
private void saveScore(Survey survey, Response response) {
String query;
if ( survey.getQuizType().equals(KNOWLEDGE_TEST) ) {
query = "com.arsdigita.simplesurvey.saveScore";
} else {
query = "com.arsdigita.simplesurvey.saveAssessmentScore";
}
DataOperation dao = SessionManager.getSession().retrieveDataOperation(query);
dao.setParameter("responseID", response.getID());
dao.execute();
}
private void addAnswer(Response surveyResponse,
PageState ps,
Object parameterValue,
String parameterName) {
s_log.debug("formData name " + parameterName + " value " + parameterValue);
Question question = getQuestion(ps, parameterName);
if (question != null ) {
PersistentLabel persistentLabel = question.getLabel();
PersistentWidget persistentWidget = question.getWidget();
surveyResponse.addAnswer(persistentLabel, persistentWidget, getStringValue(parameterValue));
}
}
private String getStringValue(Object parameterValue) {
return parameterValue == null ? "" : parameterValue.toString();
}
protected Question getQuestion(PageState ps, String parameterName) {
if (m_nameQuestionMap.get(ps) == null) {
// Populate the parameter name label id map
synchronized (this) {
Map nameQuestionMap = new HashMap();
s_log.debug("initializing the parameter name persistent label map");
PersistentForm persistentForm = (PersistentForm)m_persistentForm.get(ps);
DataAssociationCursor componentCursor = persistentForm.getComponents();
PersistentLabel lastPersistentLabel = null;
while (componentCursor.next()) {
PersistentComponent factory = (PersistentComponent) DomainObjectFactory.newInstance(componentCursor.getDataObject());
s_log.debug("iterating, component " + factory.toString());
// If this is a PersistentLabel save its id
if (factory instanceof com.arsdigita.formbuilder.PersistentLabel) {
lastPersistentLabel = (PersistentLabel)factory;
}
// Add the previous label id if this is a PersistentWidget
if (factory instanceof com.arsdigita.formbuilder.PersistentWidget) {
s_log.debug("adding to map " + ((PersistentWidget)factory).getParameterName() +
" mapped to " + lastPersistentLabel);
Question question = new Question(lastPersistentLabel,
(PersistentWidget)factory);
nameQuestionMap.put(((PersistentWidget)factory).getParameterName(), question);
}
}
m_nameQuestionMap.set(ps, nameQuestionMap);
}
}
s_log.debug("fetching label for parameter name " + parameterName);
Question question = (Question)((Map)m_nameQuestionMap.get(ps)).get(parameterName);
s_log.debug("returning " + question);
return question;
}
}

View File

@ -0,0 +1,195 @@
/*
* Copyright (C) 2002-2004 Red Hat Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package com.arsdigita.cms.contenttypes.ui;
import com.arsdigita.cms.contenttypes.util.SurveyGlobalizationUtil ;
import com.arsdigita.bebop.event.FormSectionEvent;
import com.arsdigita.bebop.event.FormProcessListener;
import com.arsdigita.bebop.event.FormInitListener;
import com.arsdigita.bebop.parameters.NotWhiteSpaceValidationListener;
import com.arsdigita.bebop.Form;
import com.arsdigita.bebop.FormProcessException;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.BlockStylable;
import com.arsdigita.bebop.form.TextField;
import com.arsdigita.bebop.form.TextArea;
import com.arsdigita.bebop.form.Date;
import com.arsdigita.bebop.form.Submit;
import com.arsdigita.bebop.form.RadioGroup;
import com.arsdigita.bebop.form.Option;
import com.arsdigita.formbuilder.PersistentForm;
import com.arsdigita.cms.contenttypes.Survey;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.lang.Boolean;
public class SurveyPropertiesForm extends Form {
private SurveySelectionModel m_survey;
private Class m_type;
private TextField m_surveyName;
private TextArea m_description;
private Date m_startDate;
private Date m_endDate;
private RadioGroup m_responsesPublic;
private RadioGroup m_quizType;
public PropertiesForm(SurveySelectionModel survey,
Class type) {
super("properties" + type.getName());
m_survey = survey;
m_type = type;
m_surveyName = new TextField("surveyName");
m_surveyName.addValidationListener(new NotWhiteSpaceValidationListener());
m_description = new TextArea("description");
m_startDate = new Date("startDate");
m_endDate = new Date("endDate");
add(new Label(GlobalizationUtil.globalize("simplesurvey.ui.admin.name")));
add(m_surveyName);
add(new Label(GlobalizationUtil.globalize("simplesurvey.ui.admin.description")));
m_description.setRows(20);
m_description.setCols(60);
add(m_description);
add(new Label(GlobalizationUtil.globalize("simplesurvey.ui.admin.start_date")));
add(m_startDate);
add(new Label(GlobalizationUtil.globalize("simplesurvey.ui.admin.end_date")));
add(m_endDate);
add(new Label(GlobalizationUtil.globalize("simplesurvey.ui.admin.should_quiz_responses_be_public")));
m_responsesPublic = new RadioGroup("responsesPublic");
Option o1 = new Option("true", new Label(GlobalizationUtil.globalize("simplesurvey.ui.admin.Yes")));
Option o2 = new Option("false", new Label(GlobalizationUtil.globalize("simplesurvey.ui.admin.No")));
m_responsesPublic.addOption(o1);
m_responsesPublic.addOption(o2);
add(m_responsesPublic);
// There can be 2 kinds of quizzes: the knowledge test kind of quiz and the personality assessment kind
add(new Label(GlobalizationUtil.globalize("simplesurvey.ui.admin.what_type_of_quiz_is_this")));
m_quizType = new RadioGroup("quizType");
Option o3 = new Option("knowledge_test", new Label(GlobalizationUtil.globalize("simplesurvey.ui.admin.knowledge_test_quiz")));
Option o4 = new Option("personal_assessment", new Label(GlobalizationUtil.globalize("simplesurvey.ui.admin.personal_assessment_quiz")));
m_quizType.addOption(o3);
m_quizType.addOption(o4);
add(m_quizType);
add(new Submit("submit"), BlockStylable.CENTER);
addInitListener(new SurveyInitListener());
addProcessListener(new PropertiesFormProcessListener());
}
private class SurveyInitListener implements FormInitListener {
public void init(FormSectionEvent e)
throws FormProcessException {
PageState state = e.getPageState();
if (m_survey.isSelected(state)) {
Survey survey = m_survey.getSelectedSurvey(state);
PersistentForm form = survey.getForm();
m_surveyName.setValue(state, form.getAdminName());
m_description.setValue(state, form.getDescription());
m_startDate.setValue(state, survey.getStartDate());
m_endDate.setValue(state, survey.getEndDate());
m_quizType.setValue(state, survey.getQuizType());
if ( survey.responsesArePublic() ) {
m_responsesPublic.setValue(state, "true");
} else {
m_responsesPublic.setValue(state,"false");
}
} else {
m_surveyName.setValue(state, "");
m_description.setValue(state, "");
Calendar startCalendar = new GregorianCalendar();
startCalendar.add(Calendar.DATE, 0);
java.util.Date startDate = startCalendar.getTime();
Calendar endCalendar = new GregorianCalendar();
endCalendar.add(Calendar.DATE, 15);
java.util.Date endDate = endCalendar.getTime();
m_startDate.setValue(state, startDate);
m_endDate.setValue(state, endDate);
m_responsesPublic.setValue(state, "true");
m_quizType.setValue(state, "knowledge_test");
}
}
}
private class PropertiesFormProcessListener implements FormProcessListener {
public void process(FormSectionEvent e)
throws FormProcessException {
PageState state = e.getPageState();
Survey survey;
PersistentForm form;
if (m_survey.isSelected(state)) {
survey = m_survey.getSelectedSurvey(state);
form = survey.getForm();
} else {
survey = m_type.equals(Survey.class) ? new Survey() : new Poll();
survey.setPackageInstance(SimpleSurveyUtil.getPackageInstance(state));
form = new PersistentForm();
survey.setForm(form);
}
form.setAdminName((String)m_surveyName.getValue(state));
form.setHTMLName(getHTMLName((String)m_surveyName.getValue(state)));
form.setDescription((String)m_description.getValue(state));
form.save();
survey.setStartDate((java.util.Date)m_startDate.getValue(state));
survey.setEndDate((java.util.Date)m_endDate.getValue(state));
survey.setResponsesPublic(new Boolean((String) m_responsesPublic.getValue(state)));
survey.setQuizType((String) m_quizType.getValue(state));
survey.save();
}
private String getHTMLName(String surveyName) {
String htmlName = surveyName.trim().toLowerCase();
htmlName = htmlName.replace(' ', '_');
return htmlName;
}
}
}

View File

@ -0,0 +1,119 @@
package com.arsdigita.cms.contenttypes.ui;
import com.arsdigita.bebop.PageState;
import com.arsdigita.cms.ContentPage;
import com.arsdigita.cms.ContentSection;
import com.arsdigita.cms.ItemSelectionModel;
import com.arsdigita.cms.ui.authoring.AuthoringKitWizard;
import com.arsdigita.cms.ui.authoring.BasicPageForm;
import com.arsdigita.cms.ui.authoring.SimpleEditStep;
import com.arsdigita.cms.ui.workflow.WorkflowLockedComponentAccess;
import com.arsdigita.domain.DomainObject;
import com.arsdigita.toolbox.ui.DomainObjectPropertySheet;
import com.arsdigita.cms.util.GlobalizationUtil;
import com.arsdigita.bebop.Component;
import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.SegmentedPanel;
import com.arsdigita.cms.contenttypes.Survey;
import com.arsdigita.cms.contenttypes.util.SurveyGlobalizationUtil;
import java.text.DateFormat;
import org.apache.log4j.Logger;
/**
* AuthoringStep for the basic properties of a basic contact
*/
public class SurveyPropertiesStep extends SimpleEditStep {
private static final Logger logger = Logger.getLogger(SurveyPropertiesStep.class);
/**
* Name of the this edit sheet (Don't know if this this really needed.
* It has the same value in almost all PropertiesStep classes)
*/
public static final String EDIT_BASIC_SHEET_NAME = "editBasic";
/**
* Constructor for the PropertiesStep.
*
* @param itemModel
* @param parent
*/
public SurveyPropertiesStep(ItemSelectionModel itemModel, AuthoringKitWizard parent) {
super(itemModel, parent);
/* Use a Segmented Panel for the multiple parts of data */
SegmentedPanel segmentedPanel = new SegmentedPanel();
setDefaultEditKey(EDIT_BASIC_SHEET_NAME);
/* The different parts of information are displayed in seperated segments each containing a SimpleEditStep */
/* Well, not so simple anymore... */
/* A new SimpleEditStep */
SimpleEditStep basicProperties = new SimpleEditStep(itemModel, parent, EDIT_BASIC_SHEET_NAME);
/* Create the edit component for this SimpleEditStep and the corresponding link */
BasicPageForm editBasicSheet = new SurveyPropertyForm(itemModel, this);
basicProperties.add(EDIT_BASIC_SHEET_NAME, (String)SurveyGlobalizationUtil.globalize("cms.contenttypes.ui.survey.edit_basic_properties").localize(), new WorkflowLockedComponentAccess(editBasicSheet, itemModel), editBasicSheet.getSaveCancelSection().getCancelButton());
/* Set the displayComponent for this step */
basicProperties.setDisplayComponent(getSurveyPropertySheet(itemModel));
/* Add the SimpleEditStep to the segmented panel */
segmentedPanel.addSegment(new Label((String)SurveyGlobalizationUtil.globalize("cms.contenttypes.ui.survey.basic_properties").localize()), basicProperties);
// If not disabled via registry, add the ui for attaching a person
if(!Survey.getConfig().getHidePerson()) {
SurveyPersonPropertiesStep personProperties = new SurveyPersonPropertiesStep(itemModel, parent);
segmentedPanel.addSegment(new Label((String)SurveyGlobalizationUtil.globalize("cms.contenttypes.ui.survey.person").localize()), personProperties);
}
// If not disabled via registry, add the ui for attaching a baseAddress
if(!Survey.getConfig().getHideAddress()) {
SurveyAddressPropertiesStep addressProperties = new SurveyAddressPropertiesStep(itemModel, parent);
segmentedPanel.addSegment(new Label((String)SurveyGlobalizationUtil.globalize("cms.contenttypes.ui.survey.address").localize()), addressProperties);
}
SurveyEntriesPropertiesStep surveyEntries = new SurveyEntriesPropertiesStep(itemModel, parent);
segmentedPanel.addSegment(new Label((String)SurveyGlobalizationUtil.globalize("cms.contenttypes.ui.survey.contactEntry").localize()), surveyEntries);
/* Sets the composed segmentedPanel as display component */
setDisplayComponent(segmentedPanel);
}
/**
* Creates and returns the sheet for editing the basic properties
* of an organization. (@see SurveyPropertyForm).
*
* @param itemModel
* @return The sheet for editing the properties of the organization.
*/
public static Component getSurveyPropertySheet(ItemSelectionModel itemModel) {
/* The DisplayComponent for the Basic Properties */
DomainObjectPropertySheet sheet = new DomainObjectPropertySheet(itemModel);
sheet.add(GlobalizationUtil.globalize("cms.contenttypes.ui.name"),"name");
sheet.add(GlobalizationUtil.globalize("cms.contenttypes.ui.title"),"title");
if(!ContentSection.getConfig().getHideLaunchDate()) {
sheet.add(GlobalizationUtil.globalize("cms.ui.authoring.page_launch_date"), ContentPage.LAUNCH_DATE, new DomainObjectPropertySheet.AttributeFormatter() {
public String format(DomainObject obj, String attribute, PageState state) {
ContentPage page = (ContentPage)obj;
if(page.getLaunchDate() != null) {
return DateFormat.getDateInstance(DateFormat.LONG).format(page.getLaunchDate());
}
else {
return (String)GlobalizationUtil.globalize("cms.ui.unknown").localize();
}
}
});
}
return sheet;
}
}

View File

@ -0,0 +1,42 @@
/*
* Copyright (C) 2002-2004 Red Hat Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package com.arsdigita.simplesurvey.ui;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.parameters.BigDecimalParameter;
import com.arsdigita.simplesurvey.Survey;
import com.arsdigita.toolbox.ui.ACSObjectSelectionModel;
public class SurveySelectionModel extends ACSObjectSelectionModel {
public SurveySelectionModel(BigDecimalParameter param) {
super(Survey.class.getName(),
Survey.BASE_DATA_OBJECT_TYPE,
param);
}
public Survey getSelectedSurvey(PageState state) {
return (Survey)getSelectedObject(state);
}
}

View File

@ -0,0 +1,33 @@
package com.arsdigita.cms.contenttypes.util;
import com.arsdigita.globalization.GlobalizedMessage;
/**
* <p>
* .
* Contains methods to simplify globalizing keys
* </p>
*
* @author Sören Bernstein
*/
public class SurveyGlobalizationUtil {
final public static String BUNDLE_NAME =
"com.arsdigita.cms.contenttypes.util.SurveyResourceBundle";
/**
* This returns a globalized message using the type specific bundle,
* BUNDLE_NAME
*/
public static GlobalizedMessage globalize(String key) {
return new GlobalizedMessage(key, BUNDLE_NAME);
}
/**
* This returns a globalized message using the type specific bundle,
* BUNDLE_NAME
*/
public static GlobalizedMessage globalize(String key, Object[] args) {
return new GlobalizedMessage(key, BUNDLE_NAME, args);
}
}

View File

@ -0,0 +1,17 @@
package com.arsdigita.cms.contenttypes.util;
import java.util.PropertyResourceBundle;
import com.arsdigita.globalization.ChainedResourceBundle;
import com.arsdigita.cms.CMSGlobalized;
public class SurveyResourceBundle extends ChainedResourceBundle implements CMSGlobalized {
public final static String SURVEY_BUNDLE_NAME =
"com.arsdigita.cms.contenttypes.SurveyResources";
public SurveyResourceBundle() {
super();
addBundle((PropertyResourceBundle) getBundle(SURVEY_BUNDLE_NAME));
addBundle((PropertyResourceBundle) getBundle(BUNDLE_NAME));
}
}

View File

@ -0,0 +1,41 @@
<!DOCTYPE stylesheet [
<!ENTITY nbsp "&#160;" ><!-- no-break space = non-breaking space, U+00A0 ISOnum -->
]>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:cms="http://www.arsdigita.com/cms/1.0"
version="1.0">
<xsl:template match="cms:item[objectType='com.arsdigita.cms.contenttypes.BaseContact']" mode="cms:CT_graphics"
name="cms:CT_graphics_com_arsdigita_cms_contenttypes_BaseContact">
<table width="435" border="0" cellspacing="0" cellpadding="0">
<tr>
<td class="contentTitle" align="left" valign="top">
<xsl:value-of select="./title"/>
</td>
</tr>
<tr>
<td>
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<xsl:if test="./address">
<tr>
<th>Address:</th>
<td class="contentText" valign="top" align="left"><xsl:value-of select="./address"/></td>
</tr>
</xsl:if>
</table>
</td>
</tr>
</table>
</xsl:template>
<xsl:template match="cms:item[objectType='com.arsdigita.cms.contenttypes.BaseContact']" mode="cms:CT_text"
name="cms:CT_text_com_arsdigita_cms_contenttypes_BaseContact">
<h1 class="title"><xsl:value-of select="./title"/></h1>
<xsl:if test="./address">
<span class="subtitle">Address</span>
<span class="text"><xsl:value-of select="./address"/></span><br/>
</xsl:if>
</xsl:template>
</xsl:stylesheet>