Example usage for java.text DateFormat setTimeZone

List of usage examples for java.text DateFormat setTimeZone

Introduction

In this page you can find the example usage for java.text DateFormat setTimeZone.

Prototype

public void setTimeZone(TimeZone zone) 

Source Link

Document

Sets the time zone for the calendar of this DateFormat object.

Usage

From source file:i5.las2peer.services.mobsos.SurveyService.java

/**
 * Marshals survey data in a result set from the MobSOS database to a JSON representation.
 *///from w ww  .  jav a 2  s .  c  o m
private JSONObject readSurveyFromResultSet(ResultSet rs) throws SQLException {

    JSONObject o = new JSONObject();

    o.put("id", rs.getInt("id"));
    o.put("name", rs.getString("name"));
    o.put("description", rs.getString("description"));
    o.put("owner", rs.getString("owner"));
    o.put("organization", rs.getString("organization"));
    o.put("logo", rs.getString("logo"));
    o.put("resource", rs.getString("resource"));
    o.put("qid", rs.getInt("qid"));

    long ts_start = rs.getTimestamp("start").getTime();
    long ts_end = rs.getTimestamp("end").getTime();

    DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
    dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));

    String d_start = dateFormat.format(new Date(ts_start));
    String d_end = dateFormat.format(new Date(ts_end));

    //System.out.println(ts_start + " -> " + d_start);
    //System.out.println(ts_end + " -> " + d_end);

    o.put("start", d_start);
    o.put("end", d_end);
    o.put("lang", rs.getString("lang"));

    return o;
}

From source file:net.bashtech.geobot.ReceiverBot.java

public String getTimeStreaming(String uptime) {
    uptime = uptime.replace("Z", "UTC");
    DateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");

    format.setTimeZone(java.util.TimeZone.getTimeZone("UTC"));
    try {//from   w  w  w.j  a  v  a2s .  c o  m
        Date then = format.parse(uptime);
        return "Streaming for " + this.getTimeTilNow(then) + ".";
    } catch (ParseException e) {
        e.printStackTrace();

    }

    return "An error occurred or stream is offline.";
}

From source file:org.codekaizen.vtj.text.BpDateFormatTest.java

/**
 * DOCUMENT ME!/*from   w  ww .  j  a  va  2  s  .c o m*/
 *
 * @throws  ParseException  DOCUMENT ME!
 */
public void testParsing() throws ParseException {
    DateFormat fmt1 = null;
    DateFormat fmt2 = null;
    Date dt1 = null;
    Date dt2 = null;
    String s = null;

    fmt1 = new BpDateFormat();

    fmt2 = new SimpleDateFormat("EEE MMM dd, yyyy");
    s = "Mon Jul 29, 2002";
    dt1 = fmt1.parse(s);
    dt2 = fmt2.parse(s);
    assertEquals(dt2, dt1);

    fmt2 = new SimpleDateFormat("EEE, MMM dd, yyyy");
    s = "Mon, Jul 29, 2002";
    dt1 = fmt1.parse(s);
    dt2 = fmt2.parse(s);
    assertEquals(dt2, dt1);

    fmt2 = new SimpleDateFormat("EEE,MMM dd, yyyy");
    s = "Mon,Jul 29, 2002";
    dt1 = fmt1.parse(s);
    dt2 = fmt2.parse(s);
    assertEquals(dt2, dt1);

    fmt2 = new SimpleDateFormat("MM/dd/yyyy");
    s = "11/17/2001";
    dt1 = fmt1.parse(s);
    dt2 = fmt2.parse(s);
    assertEquals(dt2, dt1);

    fmt2 = new SimpleDateFormat("EEEEEE MM/dd/yyyy");
    s = "Sunday 03/17/2002";
    dt1 = fmt1.parse(s);
    dt2 = fmt2.parse(s);
    assertEquals(dt2, dt1);

    fmt2 = new SimpleDateFormat("EEE MM/dd");
    s = "THU 03/14";
    dt1 = fmt1.parse(s);
    dt2 = fmt2.parse(s);
    assertEquals(dt2, dt1);

    fmt2 = new SimpleDateFormat("MM/dd");
    s = "03/14";
    dt1 = fmt1.parse(s);
    dt2 = fmt2.parse(s);
    assertEquals(dt2, dt1);

    fmt2 = new SimpleDateFormat("EEEEEE: M/dd/yyyy");
    s = "Sunday: 7/29/2002";
    dt1 = fmt1.parse(s);
    dt2 = fmt2.parse(s);
    assertEquals(dt2, dt1);

    fmt2 = new SimpleDateFormat("EEEEEEE M/dd/yy");
    s = "Tuesday 7/30/02";
    dt1 = fmt1.parse(s);
    dt2 = fmt2.parse(s);
    assertEquals(dt2, dt1);

    fmt2 = new SimpleDateFormat("M/d/yy");
    s = "7/3/02";
    dt1 = fmt1.parse(s);
    dt2 = fmt2.parse(s);
    assertEquals(dt2, dt1);

    fmt2 = new SimpleDateFormat("M-d-yy");
    s = "7-3-02";
    dt1 = fmt1.parse(s);
    dt2 = fmt2.parse(s);
    assertEquals(dt2, dt1);

    fmt2 = new SimpleDateFormat("MM-dd-yy");
    s = "07-03-02";
    dt1 = fmt1.parse(s);
    dt2 = fmt2.parse(s);
    assertEquals(dt2, dt1);

    fmt2 = new SimpleDateFormat("yyyy-MM-dd");
    s = "2002-07-03";
    dt1 = fmt1.parse(s);
    dt2 = fmt2.parse(s);
    assertEquals(dt2, dt1);

    fmt2 = new SimpleDateFormat("MM/d/yy");
    s = "12/6/01";
    dt1 = fmt1.parse(s);
    dt2 = fmt2.parse(s);
    assertEquals(dt2, dt1);

    fmt2 = new SimpleDateFormat("MMddyy");
    s = "072202";
    dt1 = fmt1.parse(s);
    dt2 = fmt2.parse(s);
    assertEquals(dt2, dt1);

    fmt2 = new SimpleDateFormat("EEE, MMM dd, yyyy");
    s = "FRI, AUG 02, 2002";
    dt1 = fmt1.parse(s);
    dt2 = fmt2.parse(s);
    assertEquals(dt2, dt1);

    fmt2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS zzz");
    s = "2002-01-21 12:00:00.000-0600";
    dt1 = fmt1.parse(s);
    dt2 = fmt2.parse("2002-01-21 12:00:00.000 CST");
    assertEquals(dt2, dt1);

    s = "2002-01-21T12:00:00.000-0600";
    dt1 = fmt1.parse(s);
    dt2 = fmt2.parse("2002-01-21 12:00:00.000 CST");
    assertEquals(dt2, dt1);

    fmt2 = new SimpleDateFormat("EEE MMM dd HH:mm:ss yyyy zzz");
    s = "Thu Jan 04 10:42:10 2001 CST";
    dt1 = fmt1.parse(s);
    dt2 = fmt2.parse(s);
    assertEquals(dt2, dt1);

    fmt2 = new SimpleDateFormat("EEE MMM dd HH:mm:ss yyyy");
    s = "Thu Jan 04 10:42:10 2001";
    dt1 = fmt1.parse(s);
    dt2 = fmt2.parse(s);
    assertEquals(dt2, dt1);

    fmt2 = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy");
    s = "Sun Jul 18 22:51:47 PDT 1999";
    dt1 = fmt1.parse(s);
    dt2 = fmt2.parse(s);
    assertEquals(dt2, dt1);

    fmt2 = new SimpleDateFormat("HH:mm:ss");
    s = "10:42:10";
    dt1 = fmt1.parse(s);
    dt2 = fmt2.parse(s);
    assertEquals(dt2, dt1);

    fmt2 = new SimpleDateFormat("hh:mm:ss aa");
    s = "10:42:10 PM";
    dt1 = fmt1.parse(s);
    dt2 = fmt2.parse(s);
    assertEquals(dt2, dt1);

    fmt2 = new SimpleDateFormat("yyyy-'W'ww");
    s = "2002-W28";
    dt1 = fmt1.parse(s);
    dt2 = fmt2.parse(s);
    assertEquals(dt2, dt1);

    fmt2 = new SimpleDateFormat("yyyy\'W\'ww");
    s = "2002W28";
    dt1 = fmt1.parse(s);
    dt2 = fmt2.parse(s);
    assertEquals(dt2, dt1);

    fmt2 = new SimpleDateFormat("HH:mm");
    s = "14:33";
    dt1 = fmt1.parse(s);
    dt2 = fmt2.parse(s);
    assertEquals(dt2, dt1);

    fmt2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS\'Z\'");
    fmt2.setTimeZone(TimeZone.getTimeZone("UTC"));
    s = "2001-01-02 14:33:18.426Z";
    dt1 = fmt1.parse(s);
    dt2 = fmt2.parse(s);
    assertEquals(dt2, dt1);

    fmt2 = new SimpleDateFormat("yyyy-MM-dd\'T\'HH:mm:ss");
    s = "2001-01-02T14:33:18";
    dt1 = fmt1.parse(s);
    dt2 = fmt2.parse(s);
    assertEquals(dt2, dt1);

    fmt2 = new SimpleDateFormat("MMM dd, yyyy");
    s = "Jan 12, 1952";
    dt1 = fmt1.parse(s);
    dt2 = fmt2.parse(s);
    assertEquals(dt2, dt1);

    fmt2 = new SimpleDateFormat("MM.dd.yy");
    s = "12.13.52";
    dt1 = fmt1.parse(s);
    dt2 = fmt2.parse(s);
    assertEquals(dt2, dt1);

    fmt2 = new SimpleDateFormat("h:mmaa");
    s = "3:30pm";
    dt1 = fmt1.parse(s);
    dt2 = fmt2.parse(s);
    assertEquals(dt2, dt1);

    fmt2 = new SimpleDateFormat("dd-MMM-yy");
    s = "12-Jan-52";
    dt1 = fmt1.parse(s);
    dt2 = fmt2.parse(s);
    assertEquals(dt2, dt1);

    fmt2 = new SimpleDateFormat("d-MMMMM-yyyy");
    s = "8-August-2002";
    dt1 = fmt1.parse(s);
    dt2 = fmt2.parse(s);
    assertEquals(dt2, dt1);

    fmt2 = new SimpleDateFormat("\'T\'HH:mm:ss");
    s = "T14:33:18";
    dt1 = fmt1.parse(s);
    dt2 = fmt2.parse(s);
    assertEquals(dt2, dt1);

    fmt2 = new SimpleDateFormat("yyyy-MM-dd\'T\'HH:mm:ssZ");
    s = "2002-01-21T12:00:00-06:00";
    dt1 = fmt1.parse(s);
    s = "2002-01-21T12:00:00-0600";
    dt2 = fmt2.parse(s);
    assertEquals(dt2, dt1);

}

From source file:org.apache.manifoldcf.crawler.connectors.rss.RSSConnector.java

/** Process a set of documents.
* This is the method that should cause each document to be fetched, processed, and the results either added
* to the queue of documents for the current job, and/or entered into the incremental ingestion manager.
* The document specification allows this class to filter what is done based on the job.
* The connector will be connected before this method can be called.
*@param documentIdentifiers is the set of document identifiers to process.
*@param statuses are the currently-stored document versions for each document in the set of document identifiers
* passed in above./*from ww  w  .  j av a 2 s  . c  om*/
*@param activities is the interface this method should use to queue up new document references
* and ingest documents.
*@param jobMode is an integer describing how the job is being run, whether continuous or once-only.
*@param usesDefaultAuthority will be true only if the authority in use for these documents is the default one.
*/
@Override
public void processDocuments(String[] documentIdentifiers, IExistingVersions statuses, Specification spec,
        IProcessActivity activities, int jobMode, boolean usesDefaultAuthority)
        throws ManifoldCFException, ServiceInterruption {
    getSession();

    // The connection limit is designed to permit this connector to coexist with potentially other connectors, such as the web connector.
    // There is currently no good way to enforce connection limits across all installed connectors - this will require considerably more
    // thought to set up properly.
    int connectionLimit = 200;

    String[] fixedList = new String[2];

    if (Logging.connectors.isDebugEnabled())
        Logging.connectors.debug("RSS: In getDocumentVersions for "
                + Integer.toString(documentIdentifiers.length) + " documents");

    Filter f = new Filter(spec, false);

    String[] acls = f.getAcls();
    // Sort it,
    java.util.Arrays.sort(acls);

    // NOTE: There are two kinds of documents in here; documents that are RSS feeds (that presumably have a content-type
    // of text/xml), and documents that need to be indexed.
    //
    // For the latter, the metadata etc is part of the version string.  For the former, the only thing that is part of the version string is the
    // document's checksum.
    //
    // The need to exclude documents from fetch based on whether they match an expression causes some difficulties, because we really
    // DON'T want this to apply to the feeds themselves.  Since the distinguishing characteristic of a feed is that it is in the seed list,
    // and that its content-type is text/xml, we could use either of these characteristics to treat feeds differently from
    // fetchable urls.  But the latter approach requires a fetch, which is forbidden.  So - the spec will be used to characterize the url.
    // However, the spec might change, and the url might be dropped from the list - and then what??
    //
    // The final solution is to simply not queue what cannot be mapped.

    int feedTimeout = f.getFeedTimeoutValue();

    // The document specification has already been used to trim out documents that are not
    // allowed from appearing in the queue.  So, even that has already been done.
    for (String documentIdentifier : documentIdentifiers) {
        // If it is in this list, we presume that it has been vetted against the map etc., so we don't do that again.  We just fetch it.
        // And, if the content type is xml, we calculate the version as if it is a feed rather than a document.

        // Get the url
        String urlValue = documentIdentifier;

        if (Logging.connectors.isDebugEnabled())
            Logging.connectors.debug("RSS: Getting version string for '" + urlValue + "'");

        String versionString;
        String ingestURL = null;
        String[] pubDates = null;
        String[] sources = null;
        String[] titles = null;
        String[] authorNames = null;
        String[] authorEmails = null;
        String[] categories = null;
        String[] descriptions = null;

        try {
            // If there's a carrydown "data" value for this url, we use that value rather than actually fetching the document.  This also means we don't need to
            // do a robots check, because we aren't actually crawling anything.  So, ALWAYS do this first...
            CharacterInput[] dechromedData = activities.retrieveParentDataAsFiles(urlValue, "data");
            try {
                if (dechromedData.length > 0) {
                    // Data already available.  The fetch cycle can be entirely avoided, as can the robots check.
                    ingestURL = f.mapDocumentURL(urlValue);
                    if (ingestURL != null) {
                        // Open up an input stream corresponding to the carrydown data.  The stream will be encoded as utf-8.
                        try {
                            InputStream is = dechromedData[0].getUtf8Stream();
                            try {
                                StringBuilder sb = new StringBuilder();
                                long checkSum = cache.addData(activities, urlValue, "text/html", is);
                                // Grab what we need from the passed-down data for the document.  These will all become part
                                // of the version string.
                                pubDates = activities.retrieveParentData(urlValue, "pubdate");
                                sources = activities.retrieveParentData(urlValue, "source");
                                titles = activities.retrieveParentData(urlValue, "title");
                                authorNames = activities.retrieveParentData(urlValue, "authorname");
                                authorEmails = activities.retrieveParentData(urlValue, "authoremail");
                                categories = activities.retrieveParentData(urlValue, "category");
                                descriptions = activities.retrieveParentData(urlValue, "description");
                                java.util.Arrays.sort(pubDates);
                                java.util.Arrays.sort(sources);
                                java.util.Arrays.sort(titles);
                                java.util.Arrays.sort(authorNames);
                                java.util.Arrays.sort(authorEmails);
                                java.util.Arrays.sort(categories);
                                java.util.Arrays.sort(descriptions);

                                if (sources.length == 0) {
                                    if (Logging.connectors.isDebugEnabled())
                                        Logging.connectors.debug("RSS: Warning; URL '" + ingestURL
                                                + "' doesn't seem to have any RSS feed source!");
                                }

                                sb.append('+');
                                packList(sb, acls, '+');
                                if (acls.length > 0) {
                                    sb.append('+');
                                    pack(sb, defaultAuthorityDenyToken, '+');
                                } else
                                    sb.append('-');
                                // The ingestion URL
                                pack(sb, ingestURL, '+');
                                // The pub dates
                                packList(sb, pubDates, '+');
                                // The titles
                                packList(sb, titles, '+');
                                // The sources
                                packList(sb, sources, '+');
                                // The categories
                                packList(sb, categories, '+');
                                // The descriptions
                                packList(sb, descriptions, '+');
                                // The author names
                                packList(sb, authorNames, '+');
                                // The author emails
                                packList(sb, authorEmails, '+');

                                // Do the checksum part, which does not need to be parseable.
                                sb.append(new Long(checkSum).toString());

                                versionString = sb.toString();
                            } finally {
                                is.close();
                            }
                        } catch (java.net.SocketTimeoutException e) {
                            throw new ManifoldCFException(
                                    "IO exception reading data from string: " + e.getMessage(), e);
                        } catch (InterruptedIOException e) {
                            throw new ManifoldCFException("Interrupted: " + e.getMessage(), e,
                                    ManifoldCFException.INTERRUPTED);
                        } catch (IOException e) {
                            throw new ManifoldCFException(
                                    "IO exception reading data from string: " + e.getMessage(), e);
                        }
                    } else {
                        // Document a seed or unmappable; just skip
                        if (Logging.connectors.isDebugEnabled())
                            Logging.connectors.debug("RSS: Skipping carry-down document '" + urlValue
                                    + "' because it is unmappable or is a seed.");
                    }
                } else {
                    // Get the old version string
                    String oldVersionString = statuses.getIndexedVersionString(documentIdentifier);

                    // Unpack the old version as much as possible.
                    // We are interested in what the ETag and Last-Modified headers were last time.
                    String lastETagValue = null;
                    String lastModifiedValue = null;
                    // Note well: Non-continuous jobs cannot use etag because the rss document MUST be fetched each time for such jobs,
                    // or the documents it points at would get deleted.
                    //
                    // NOTE: I disabled this code because we really need the feed's TTL value in order to reschedule properly.  I can't get the
                    // TTL value without refetching the document - therefore ETag and Last-Modified cannot be used :-(
                    if (false && jobMode == JOBMODE_CONTINUOUS && oldVersionString != null
                            && oldVersionString.startsWith("-")) {
                        // It's a feed, so the last etag and last-modified fields should be encoded in this version string.
                        StringBuilder lastETagBuffer = new StringBuilder();
                        int unpackPos = unpack(lastETagBuffer, oldVersionString, 1, '+');
                        StringBuilder lastModifiedBuffer = new StringBuilder();
                        unpackPos = unpack(lastModifiedBuffer, oldVersionString, unpackPos, '+');
                        if (lastETagBuffer.length() > 0)
                            lastETagValue = lastETagBuffer.toString();
                        if (lastModifiedBuffer.length() > 0)
                            lastModifiedValue = lastModifiedBuffer.toString();
                    }

                    if (Logging.connectors.isDebugEnabled()
                            && (lastETagValue != null || lastModifiedValue != null))
                        Logging.connectors.debug(
                                "RSS: Document '" + urlValue + "' was found to have a previous ETag value of '"
                                        + ((lastETagValue == null) ? "null" : lastETagValue)
                                        + "' and a previous Last-Modified value of '"
                                        + ((lastModifiedValue == null) ? "null" : lastModifiedValue) + "'");

                    // Robots check.  First, we need to separate the url into its components
                    URL url;
                    try {
                        url = new URL(urlValue);
                    } catch (MalformedURLException e) {
                        Logging.connectors.debug("RSS: URL '" + urlValue + "' is malformed; skipping", e);
                        activities.deleteDocument(documentIdentifier);
                        continue;
                    }

                    String protocol = url.getProtocol();
                    int port = url.getPort();
                    String hostName = url.getHost();
                    String pathPart = url.getFile();

                    // Check with robots to see if it's allowed
                    if (robotsUsage >= ROBOTS_DATA && !robots.isFetchAllowed(currentContext, throttleGroupName,
                            protocol, port, hostName, url.getPath(), userAgent, from, proxyHost, proxyPort,
                            proxyAuthDomain, proxyAuthUsername, proxyAuthPassword, activities,
                            connectionLimit)) {
                        activities.recordActivity(null, ACTIVITY_FETCH, null, urlValue, Integer.toString(-2),
                                "Robots exclusion", null);

                        if (Logging.connectors.isDebugEnabled())
                            Logging.connectors
                                    .debug("RSS: Skipping url '" + urlValue + "' because robots.txt says to");
                        activities.deleteDocument(documentIdentifier);
                        continue;
                    }

                    // Now, use the fetcher, and get the file.
                    IThrottledConnection connection = fetcher.createConnection(currentContext,
                            throttleGroupName, hostName, connectionLimit, feedTimeout, proxyHost, proxyPort,
                            proxyAuthDomain, proxyAuthUsername, proxyAuthPassword, activities);
                    try {
                        // Begin the fetch
                        connection.beginFetch("Data");
                        try {
                            // Execute the request.
                            // Use the connect timeout from the document specification!
                            int status = connection.executeFetch(protocol, port, pathPart, userAgent, from,
                                    lastETagValue, lastModifiedValue);
                            switch (status) {
                            case IThrottledConnection.STATUS_NOCHANGE:
                                versionString = oldVersionString;
                                break;
                            case IThrottledConnection.STATUS_OK:
                                try {
                                    if (Logging.connectors.isDebugEnabled())
                                        Logging.connectors.debug("RSS: Successfully fetched " + urlValue);
                                    // Document successfully fetched!
                                    // If its content is xml, presume it's a feed...
                                    String contentType = connection.getResponseHeader("Content-Type");
                                    // Some sites have multiple content types.  We just look at the LAST one in that case.
                                    if (contentType != null) {
                                        String[] contentTypes = contentType.split(",");
                                        if (contentTypes.length > 0)
                                            contentType = contentTypes[contentTypes.length - 1].trim();
                                        else
                                            contentType = null;
                                    }
                                    String strippedContentType = contentType;
                                    if (strippedContentType != null) {
                                        int pos = strippedContentType.indexOf(";");
                                        if (pos != -1)
                                            strippedContentType = strippedContentType.substring(0, pos).trim();
                                    }
                                    boolean isXML = (strippedContentType != null
                                            && xmlContentTypes.contains(strippedContentType));
                                    ingestURL = null;
                                    if (!isXML) {
                                        // If the chromed content mode is set to "skip", and we got here, it means
                                        // we should not include the content.
                                        if (f.getChromedContentMode() == CHROMED_SKIP) {
                                            if (Logging.connectors.isDebugEnabled())
                                                Logging.connectors.debug("RSS: Removing url '" + urlValue
                                                        + "' because it no longer has dechromed content available");
                                            versionString = null;
                                            break;
                                        }

                                        // Decide whether to exclude this document based on what we see here.
                                        // Basically, we want to get rid of everything that we don't know what
                                        // to do with in the ingestion system.
                                        if (!activities.checkMimeTypeIndexable(contentType)) {
                                            if (Logging.connectors.isDebugEnabled())
                                                Logging.connectors.debug("RSS: Removing url '" + urlValue
                                                        + "' because it had the wrong content type: "
                                                        + ((contentType == null) ? "null"
                                                                : "'" + contentType + "'"));
                                            versionString = null;
                                            break;
                                        }

                                        ingestURL = f.mapDocumentURL(urlValue);
                                    } else {
                                        if (Logging.connectors.isDebugEnabled())
                                            Logging.connectors
                                                    .debug("RSS: The url '" + urlValue + "' is a feed");

                                        if (!f.isSeed(urlValue)) {
                                            // Remove the feed from consideration, since it has left the list of seeds
                                            if (Logging.connectors.isDebugEnabled())
                                                Logging.connectors.debug("RSS: Removing feed url '" + urlValue
                                                        + "' because it is not a seed.");
                                            versionString = null;
                                            break;
                                        }
                                    }

                                    InputStream is = connection.getResponseBodyStream();
                                    try {
                                        long checkSum = cache.addData(activities, urlValue, contentType, is);
                                        StringBuilder sb = new StringBuilder();
                                        if (ingestURL != null) {
                                            // We think it is ingestable.  The version string accordingly starts with a "+".

                                            // Grab what we need from the passed-down data for the document.  These will all become part
                                            // of the version string.
                                            pubDates = activities.retrieveParentData(urlValue, "pubdate");
                                            sources = activities.retrieveParentData(urlValue, "source");
                                            titles = activities.retrieveParentData(urlValue, "title");
                                            authorNames = activities.retrieveParentData(urlValue, "authorname");
                                            authorEmails = activities.retrieveParentData(urlValue,
                                                    "authoremail");
                                            categories = activities.retrieveParentData(urlValue, "category");
                                            descriptions = activities.retrieveParentData(urlValue,
                                                    "description");
                                            java.util.Arrays.sort(pubDates);
                                            java.util.Arrays.sort(sources);
                                            java.util.Arrays.sort(titles);
                                            java.util.Arrays.sort(authorNames);
                                            java.util.Arrays.sort(authorEmails);
                                            java.util.Arrays.sort(categories);
                                            java.util.Arrays.sort(descriptions);

                                            if (sources.length == 0) {
                                                if (Logging.connectors.isDebugEnabled())
                                                    Logging.connectors.debug("RSS: Warning; URL '" + ingestURL
                                                            + "' doesn't seem to have any RSS feed source!");
                                            }

                                            sb.append('+');
                                            packList(sb, acls, '+');
                                            if (acls.length > 0) {
                                                sb.append('+');
                                                pack(sb, defaultAuthorityDenyToken, '+');
                                            } else
                                                sb.append('-');
                                            // The ingestion URL
                                            pack(sb, ingestURL, '+');
                                            // The pub dates
                                            packList(sb, pubDates, '+');
                                            // The titles
                                            packList(sb, titles, '+');
                                            // The sources
                                            packList(sb, sources, '+');
                                            // The categories
                                            packList(sb, categories, '+');
                                            // The descriptions
                                            packList(sb, descriptions, '+');
                                            // The author names
                                            packList(sb, authorNames, '+');
                                            // The author emails
                                            packList(sb, authorEmails, '+');
                                        } else {
                                            sb.append('-');
                                            String etag = connection.getResponseHeader("ETag");
                                            if (etag == null)
                                                pack(sb, "", '+');
                                            else
                                                pack(sb, etag, '+');
                                            String lastModified = connection.getResponseHeader("Last-Modified");
                                            if (lastModified == null)
                                                pack(sb, "", '+');
                                            else
                                                pack(sb, lastModified, '+');

                                        }

                                        // Do the checksum part, which does not need to be parseable.
                                        sb.append(new Long(checkSum).toString());

                                        versionString = sb.toString();
                                    } finally {
                                        is.close();
                                    }
                                } catch (java.net.SocketTimeoutException e) {
                                    Logging.connectors
                                            .warn("RSS: Socket timeout exception fetching document contents '"
                                                    + urlValue + "' - skipping: " + e.getMessage(), e);
                                    versionString = null;
                                } catch (ConnectTimeoutException e) {
                                    Logging.connectors
                                            .warn("RSS: Connecto timeout exception fetching document contents '"
                                                    + urlValue + "' - skipping: " + e.getMessage(), e);
                                    versionString = null;
                                } catch (InterruptedIOException e) {
                                    throw new ManifoldCFException("Interrupted: " + e.getMessage(), e,
                                            ManifoldCFException.INTERRUPTED);
                                } catch (IOException e) {
                                    Logging.connectors.warn("RSS: IO exception fetching document contents '"
                                            + urlValue + "' - skipping: " + e.getMessage(), e);
                                    versionString = null;
                                }

                                break;

                            case IThrottledConnection.STATUS_SITEERROR:
                            case IThrottledConnection.STATUS_PAGEERROR:
                            default:
                                // Record an *empty* version.
                                // This signals the processDocuments() method that we really don't want to ingest this document, but we also don't
                                // want to blow the document out of the queue, since then we'd wind up perhaps fetching it multiple times.
                                versionString = "";
                                break;
                            }
                        } finally {
                            connection.doneFetch(activities);
                        }
                    } finally {
                        connection.close();
                    }

                    if (versionString == null) {
                        activities.deleteDocument(documentIdentifier);
                        continue;
                    }

                    if (!(versionString.length() == 0
                            || activities.checkDocumentNeedsReindexing(documentIdentifier, versionString)))
                        continue;

                    // Process document!
                    if (Logging.connectors.isDebugEnabled())
                        Logging.connectors.debug("RSS: Processing '" + urlValue + "'");

                    // The only links we extract come from documents that we think are RSS feeds.
                    // When we think that's the case, we attempt to parse it as RSS XML.
                    if (ingestURL == null) {
                        if (Logging.connectors.isDebugEnabled())
                            Logging.connectors.debug("RSS: Interpreting document '" + urlValue + "' as a feed");

                        // We think it is a feed.
                        // If this is a continuous job, AND scanonly is true, it means that the document was either identical to the
                        // previous fetch, or was not fetched at all.  In that case, it may not even be there, and we *certainly* don't
                        // want to attempt to process it in any case.
                        //

                        // NOTE: I re-enabled the scan permanently because we need the TTL value to be set whatever the cost.  If the
                        // TTL value is not set, we default to the specified job's feed-rescan time, which is not going to be current enough for some feeds.
                        if (true || jobMode != JOBMODE_CONTINUOUS) {
                            handleRSSFeedSAX(urlValue, activities, f);
                            if (Logging.connectors.isDebugEnabled())
                                Logging.connectors.debug("RSS: Extraction of feed '" + urlValue + "' complete");

                            // Record the feed's version string, so we won't refetch unless needed.
                            // This functionality is required for the last ETag and Last-Modified fields to be sent to the rss server, and to
                            // keep track of the adaptive parameters.
                            activities.recordDocument(documentIdentifier, versionString);
                        } else {
                            // The problem here is that we really do need to set the rescan time to something reasonable.
                            // But we might not even have read the feed!  So what to do??
                            // One answer is to build a connector-specific table that carries the last value of every feed around.
                            // Another answer is to change the version code to always read the feed (and the heck with ETag and Last-Modified).
                            if (Logging.connectors.isDebugEnabled())
                                Logging.connectors.debug("RSS: Feed '" + urlValue
                                        + "' does not appear to differ from previous fetch for a continuous job; not extracting!");

                            long currentTime = System.currentTimeMillis();

                            Long defaultRescanTime = f.getDefaultRescanTime(currentTime);

                            if (defaultRescanTime != null) {
                                Long minimumTime = f.getMinimumRescanTime(currentTime);
                                if (minimumTime != null) {
                                    if (defaultRescanTime.longValue() < minimumTime.longValue())
                                        defaultRescanTime = minimumTime;
                                }
                            }

                            activities.setDocumentScheduleBounds(urlValue, defaultRescanTime, defaultRescanTime,
                                    null, null);

                        }
                    } else {
                        if (Logging.connectors.isDebugEnabled())
                            Logging.connectors.debug("RSS: Interpreting '" + urlValue + "' as a document");

                        String errorCode = null;
                        String errorDesc = null;
                        long startTime = System.currentTimeMillis();
                        Long fileLengthLong = null;
                        try {
                            long documentLength = cache.getDataLength(documentIdentifier);
                            if (!activities.checkLengthIndexable(documentLength)) {
                                activities.noDocument(documentIdentifier, versionString);
                                errorCode = activities.EXCLUDED_LENGTH;
                                errorDesc = "Document rejected because of length (" + documentLength + ")";
                                if (Logging.connectors.isDebugEnabled())
                                    Logging.connectors.debug("RSS: Skipping document '" + urlValue
                                            + "' because its length was rejected (" + documentLength + ")");
                                continue;
                            }

                            if (!activities.checkURLIndexable(documentIdentifier)) {
                                activities.noDocument(documentIdentifier, versionString);
                                errorCode = activities.EXCLUDED_URL;
                                errorDesc = "Document rejected because of URL ('" + documentIdentifier + "')";
                                if (Logging.connectors.isDebugEnabled())
                                    Logging.connectors.debug("RSS: Skipping document '" + urlValue
                                            + "' because its URL was rejected ('" + documentIdentifier + "')");
                                continue;
                            }

                            // Check if it's a recognized content type
                            String contentType = cache.getContentType(documentIdentifier);
                            // Some sites have multiple content types.  We just look at the LAST one in that case.
                            if (contentType != null) {
                                String[] contentTypes = contentType.split(",");
                                if (contentTypes.length > 0)
                                    contentType = contentTypes[contentTypes.length - 1].trim();
                                else
                                    contentType = null;
                            }
                            if (!activities.checkMimeTypeIndexable(contentType)) {
                                activities.noDocument(documentIdentifier, versionString);
                                errorCode = activities.EXCLUDED_MIMETYPE;
                                errorDesc = "Document rejected because of mime type (" + contentType + ")";
                                if (Logging.connectors.isDebugEnabled())
                                    Logging.connectors.debug("RSS: Skipping document '" + urlValue
                                            + "' because its mime type was rejected ('" + contentType + "')");
                                continue;
                            }

                            // Treat it as an ingestable document.

                            long dataSize = cache.getDataLength(urlValue);
                            RepositoryDocument rd = new RepositoryDocument();

                            // Set content type
                            if (contentType != null)
                                rd.setMimeType(contentType);

                            // Turn into acls and add into description
                            String[] denyAcls;
                            if (acls == null)
                                denyAcls = null;
                            else if (acls.length == 0)
                                denyAcls = new String[0];
                            else
                                denyAcls = new String[] { defaultAuthorityDenyToken };

                            if (acls != null && denyAcls != null)
                                rd.setSecurity(RepositoryDocument.SECURITY_TYPE_DOCUMENT, acls, denyAcls);

                            if (titles != null && titles.length > 0)
                                rd.addField("title", titles);
                            if (authorNames != null && authorNames.length > 0)
                                rd.addField("authorname", authorNames);
                            if (authorEmails != null && authorEmails.length > 0)
                                rd.addField("authoremail", authorEmails);
                            if (descriptions != null && descriptions.length > 0)
                                rd.addField("summary", descriptions);
                            if (sources != null && sources.length > 0)
                                rd.addField("source", sources);
                            if (categories != null && categories.length > 0)
                                rd.addField("category", categories);

                            // The pubdates are a ms since epoch value; we want the minimum one for the origination time.
                            Long minimumOrigTime = null;
                            if (pubDates != null && pubDates.length > 0) {
                                String[] pubDateValuesISO = new String[pubDates.length];
                                TimeZone tz = TimeZone.getTimeZone("UTC");
                                DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'");
                                df.setTimeZone(tz);
                                for (int k = 0; k < pubDates.length; k++) {
                                    String pubDate = pubDates[k];
                                    try {
                                        Long pubDateLong = new Long(pubDate);
                                        if (minimumOrigTime == null
                                                || pubDateLong.longValue() < minimumOrigTime.longValue())
                                            minimumOrigTime = pubDateLong;
                                        pubDateValuesISO[k] = df.format(new Date(pubDateLong.longValue()));
                                    } catch (NumberFormatException e) {
                                        // Do nothing; the version string seems to not mean anything
                                        pubDateValuesISO[k] = "";
                                    }
                                }
                                rd.addField("pubdate", pubDates);
                                rd.addField("pubdateiso", pubDateValuesISO);
                            }

                            if (minimumOrigTime != null)
                                activities.setDocumentOriginationTime(urlValue, minimumOrigTime);

                            InputStream is = cache.getData(urlValue);
                            if (is != null) {
                                try {
                                    rd.setBinary(is, dataSize);
                                    try {
                                        activities.ingestDocumentWithException(documentIdentifier,
                                                versionString, ingestURL, rd);
                                        errorCode = "OK";
                                        fileLengthLong = new Long(dataSize);
                                    } catch (IOException e) {
                                        errorCode = e.getClass().getSimpleName().toUpperCase(Locale.ROOT);
                                        errorDesc = e.getMessage();
                                        handleIOException(e, "reading data");
                                    }
                                } finally {
                                    try {
                                        is.close();
                                    } catch (IOException e) {
                                        errorCode = e.getClass().getSimpleName().toUpperCase(Locale.ROOT);
                                        errorDesc = e.getMessage();
                                        handleIOException(e, "closing stream");
                                    }
                                }
                            }
                        } catch (ManifoldCFException e) {
                            if (e.getErrorCode() == ManifoldCFException.INTERRUPTED)
                                errorCode = null;
                            throw e;
                        } finally {
                            if (errorCode != null)
                                activities.recordActivity(new Long(startTime), ACTIVITY_PROCESS, null, urlValue,
                                        errorCode, errorDesc, null);
                        }
                    }
                }
            } finally {
                for (CharacterInput ci : dechromedData) {
                    if (ci != null)
                        ci.discard();
                }

            }
        } finally {
            // Remove any fetched documents.
            cache.deleteData(documentIdentifier);
        }
    }
}

From source file:org.sakaiproject.calendar.tool.CalendarAction.java

/**
 * Build the context for showing week view
 *///from   w w  w .j av  a2 s.com
protected void buildWeekContext(VelocityPortlet portlet, Context context, RunData runData,
        CalendarActionState state) {
    Calendar calendarObj = null;
    //Time st,et = null;
    //CalendarUtil calObj= null;
    MyYear yearObj = null;
    MyMonth monthObj1 = null;
    MyWeek weekObj = null;
    MyDay dayObj = null;
    MyDate dateObj1, dateObj2 = null;
    int dayofweek = 0;

    // new objects of myYear, myMonth, myDay, myWeek classes
    yearObj = new MyYear();
    monthObj1 = new MyMonth();
    weekObj = new MyWeek();
    dayObj = new MyDay();
    dateObj1 = new MyDate();
    CalendarEventVector CalendarEventVectorObj = null;

    //calObj = state.getCalObj();
    String peid = ((JetspeedRunData) runData).getJs_peid();
    SessionState sstate = ((JetspeedRunData) runData).getPortletSessionState(peid);

    Time m_time = TimeService.newTime();
    TimeBreakdown b = m_time.breakdownLocal();
    int stateYear = b.getYear();
    int stateMonth = b.getMonth();
    int stateDay = b.getDay();
    if ((sstate.getAttribute(STATE_YEAR) != null) && (sstate.getAttribute(STATE_MONTH) != null)
            && (sstate.getAttribute(STATE_DAY) != null)) {
        stateYear = ((Integer) sstate.getAttribute(STATE_YEAR)).intValue();
        stateMonth = ((Integer) sstate.getAttribute(STATE_MONTH)).intValue();
        stateDay = ((Integer) sstate.getAttribute(STATE_DAY)).intValue();
    }

    CalendarUtil calObj = new CalendarUtil();
    calObj.setDay(stateYear, stateMonth, stateDay);
    int iii = 0;

    dateObj1.setTodayDate(calObj.getMonthInteger(), calObj.getDayOfMonth(), calObj.getYear());
    yearObj.setYear(calObj.getYear());
    monthObj1.setMonth(calObj.getMonthInteger());
    dayObj.setDay(calObj.getDayOfMonth());
    String calId = state.getPrimaryCalendarReference();

    // this loop will move the calendar to the begining of the week

    if (CalendarService.allowGetCalendar(calId) == false) {
        context.put(ALERT_MSG_KEY, rb.getString("java.alert.younotallow"));
        return;
    } else {
        try {
            calendarObj = CalendarService.getCalendar(calId);
        } catch (IdUnusedException e) {
            try {
                CalendarService.commitCalendar(CalendarService.addCalendar(calId));
                calendarObj = CalendarService.getCalendar(calId);
            } catch (Exception err) {
                context.put(ALERT_MSG_KEY, rb.getString("java.alert.therenoactv"));
                M_log.debug(".buildWeekContext(): " + err);
                return;
            }
        } catch (PermissionException e) {
            context.put(ALERT_MSG_KEY, rb.getString("java.alert.younotperm"));
            M_log.debug(".buildWeekContext(): " + e);
            return;
        }
    }

    if (calendarObj.allowGetEvents() == true) {
        CalendarEventVectorObj = CalendarService.getEvents(
                getCalendarReferenceList(portlet, state.getPrimaryCalendarReference(), isOnWorkspaceTab()),
                getWeekTimeRange(calObj));
    } else {
        CalendarEventVectorObj = new CalendarEventVector();
    }

    calObj.setDay(dateObj1.getYear(), dateObj1.getMonth(), dateObj1.getDay());
    dayofweek = calObj.getDay_Of_Week(true);
    calObj.setPrevDate(dayofweek - 1);

    dayofweek = calObj.getDay_Of_Week(true);

    Time[] pageStartTime = new Time[7];
    Time[] pageEndTime = new Time[7];

    for (int i = 7; i >= dayofweek; i--) {

        Vector eventVector = new Vector();
        Vector eventVector1;
        dateObj2 = new MyDate();
        dateObj2.setTodayDate(calObj.getMonthInteger(), calObj.getDayOfMonth(), calObj.getYear());
        dateObj2.setDayName(calendarUtilGetDay(calObj.getDay_Of_Week(true)));
        dateObj2.setNameOfMonth(calendarUtilGetMonth(calObj.getMonthInteger()));

        if (calObj.getDayOfMonth() == dayObj.getDay())
            dateObj2.setFlag(1);

        if (state.getCurrentPage().equals("third")) {
            eventVector1 = new Vector();
            // JS -- the third page starts at 2PM(14 o'clock), and lasts 20 half-hour
            eventVector = getNewEvents(calObj.getYear(), calObj.getMonthInteger(), calObj.getDayOfMonth(),
                    state, runData, THIRD_PAGE_START_HOUR, 19, context, CalendarEventVectorObj);

            for (int index = 0; index < eventVector1.size(); index++) {
                eventVector.add(eventVector.size(), eventVector1.get(index));
            }

            // Reminder: weekview vm is using 0..6
            pageStartTime[i - 1] = TimeService.newTimeLocal(calObj.getYear(), calObj.getMonthInteger(),
                    calObj.getDayOfMonth(), THIRD_PAGE_START_HOUR, 0, 0, 0);
            pageEndTime[i - 1] = TimeService.newTimeLocal(calObj.getYear(), calObj.getMonthInteger(),
                    calObj.getDayOfMonth(), 23, 59, 0, 0);

        } else if (state.getCurrentPage().equals("second")) {
            eventVector = getNewEvents(calObj.getYear(), calObj.getMonthInteger(), calObj.getDayOfMonth(),
                    state, runData, SECOND_PAGE_START_HOUR, 19, context, CalendarEventVectorObj);
            // Reminder: weekview vm is using 0..6
            pageStartTime[i - 1] = TimeService.newTimeLocal(calObj.getYear(), calObj.getMonthInteger(),
                    calObj.getDayOfMonth(), SECOND_PAGE_START_HOUR, 0, 0, 0);
            pageEndTime[i - 1] = TimeService.newTimeLocal(calObj.getYear(), calObj.getMonthInteger(),
                    calObj.getDayOfMonth(), 17, 59, 0, 0);

        } else {
            eventVector1 = new Vector();
            // JS -- the first page starts at 12AM(0 o'clock), and lasts 20 half-hour
            eventVector1 = getNewEvents(calObj.getYear(), calObj.getMonthInteger(), calObj.getDayOfMonth(),
                    state, runData, FIRST_PAGE_START_HOUR, 19, context, CalendarEventVectorObj);

            for (int index = 0; index < eventVector1.size(); index++) {
                eventVector.insertElementAt(eventVector1.get(index), index);
            }

            // Reminder: weekview vm is using 0..6
            pageStartTime[i - 1] = TimeService.newTimeLocal(calObj.getYear(), calObj.getMonthInteger(),
                    calObj.getDayOfMonth(), 0, 0, 0, 0);
            pageEndTime[i - 1] = TimeService.newTimeLocal(calObj.getYear(), calObj.getMonthInteger(),
                    calObj.getDayOfMonth(), 9, 59, 0, 0);

        }
        dateObj2.setEventBerWeek(eventVector);
        weekObj.setWeek(7 - i, dateObj2);

        // the purpose of this if condition is to check if we reached day 7 if yes do not
        // call next day.
        if (i > dayofweek)
            calObj.nextDate();
    }

    calObj.setDay(yearObj.getYear(), monthObj1.getMonth(), dayObj.getDay());
    context.put("week", weekObj);
    context.put("helper", new Helper());
    context.put("date", dateObj1);
    context.put("page", state.getCurrentPage());
    state.setState("week");
    context.put("tlang", rb);
    context.put("config", configProps);
    context.put("message", state.getState());

    DateFormat formatter = DateFormat.getDateInstance(DateFormat.FULL, new ResourceLoader().getLocale());
    formatter.setTimeZone(TimeService.getLocalTimeZone());
    try {
        context.put("beginWeek", formatter.format(calObj.getPrevTime(calObj.getDay_Of_Week(true) - 1)));
    } catch (Exception e) {
        context.put("beginWeek", calObj.getTodayDate());
    }
    try {
        calObj.setNextWeek();
        context.put("endWeek", formatter.format(calObj.getPrevTime(1)));
    } catch (Exception e) {
        context.put("endWeek", calObj.getTodayDate());
    }

    buildMenu(portlet, context, runData, state,
            CalendarPermissions.allowCreateEvents(state.getPrimaryCalendarReference(),
                    state.getSelectedCalendarReference()),
            CalendarPermissions.allowDeleteEvent(state.getPrimaryCalendarReference(),
                    state.getSelectedCalendarReference(), state.getCalendarEventId()),
            CalendarPermissions.allowReviseEvents(state.getPrimaryCalendarReference(),
                    state.getSelectedCalendarReference(), state.getCalendarEventId()),
            CalendarPermissions.allowMergeCalendars(state.getPrimaryCalendarReference()),
            CalendarPermissions.allowModifyCalendarProperties(state.getPrimaryCalendarReference()),
            CalendarPermissions.allowImport(state.getPrimaryCalendarReference()),
            CalendarPermissions.allowSubscribe(state.getPrimaryCalendarReference()),
            CalendarPermissions.allowSubscribeThis(state.getPrimaryCalendarReference()));

    calObj.setDay(yearObj.getYear(), monthObj1.getMonth(), dayObj.getDay());

    context.put("realDate", TimeService.newTime());
    context.put("tlang", rb);
    context.put("config", configProps);
    Vector vec = new Vector();
    context.put("vec", vec);
    Vector conflictVec = new Vector();
    context.put("conflictVec", conflictVec);
    Vector calVec = new Vector();
    context.put("calVec", calVec);
    HashMap hm = new HashMap();
    context.put("hm", hm);
    Integer intObj = Integer.valueOf(0);
    context.put("intObj", intObj);

    context.put("pageStartTime", pageStartTime);
    context.put("pageEndTime", pageEndTime);

    context.put("selectedView", rb.getString("java.byweek"));

    context.put("dayOfWeekNames", calObj.getCalendarDaysOfWeekNames(false));

}

From source file:org.sakaiproject.lessonbuildertool.tool.producers.ShowPageProducer.java

public void fillComponents(UIContainer tofill, ViewParameters viewParams, ComponentChecker checker) {
    GeneralViewParameters params = (GeneralViewParameters) viewParams;

    UIOutput.make(tofill, "html")
            .decorate(new UIFreeAttributeDecorator("lang", localegetter.get().getLanguage()))
            .decorate(new UIFreeAttributeDecorator("xml:lang", localegetter.get().getLanguage()));

    UIOutput.make(tofill, "datepicker").decorate(
            new UIFreeAttributeDecorator("src", (majorVersion >= 10 ? "/library" : "/lessonbuilder-tool")
                    + "/js/lang-datepicker/lang-datepicker.js"));

    boolean iframeJavascriptDone = false;

    // security model:
    // canEditPage and canReadPage are normal Sakai privileges. They apply

    // to all/*from  w  w w  . ja v  a2 s.  c  o m*/
    // pages in the site.
    // However when presented with a page, we need to make sure it's
    // actually in
    // this site, or users could get to pages in other sites. That's done
    // by updatePageObject. The model is that producers always work on the
    // current page, and updatePageObject makes sure that is in the current
    // site.
    // At that point we can safely use canEditPage.

    // somewhat misleading. sendingPage specifies the page we're supposed to
    // go to.  If path is "none", we don't want this page to be what we see
    // when we come back to the tool
    if (params.getSendingPage() != -1) {
        // will fail if page not in this site
        // security then depends upon making sure that we only deal with
        // this page
        try {
            simplePageBean.updatePageObject(params.getSendingPage(), !params.getPath().equals("none"));
        } catch (Exception e) {
            log.warn("ShowPage permission exception " + e);
            UIOutput.make(tofill, "error-div");
            UIOutput.make(tofill, "error", messageLocator.getMessage("simplepage.not_available"));
            return;
        }
    }

    boolean canEditPage = simplePageBean.canEditPage();
    boolean canReadPage = simplePageBean.canReadPage();
    boolean canSeeAll = simplePageBean.canSeeAll(); // always on if caneditpage

    boolean cameFromGradingPane = params.getPath().equals("none");

    TimeZone localtz = timeService.getLocalTimeZone();
    isoDateFormat.setTimeZone(localtz);

    if (!canReadPage) {
        // this code is intended for the situation where site permissions
        // haven't been set up.
        // So if the user can't read the page (which is pretty abnormal),
        // see if they have site.upd.
        // if so, give them some explanation and offer to call the
        // permissions helper
        String ref = "/site/" + simplePageBean.getCurrentSiteId();
        if (simplePageBean.canEditSite()) {
            SimplePage currentPage = simplePageBean.getCurrentPage();
            UIOutput.make(tofill, "needPermissions");

            GeneralViewParameters permParams = new GeneralViewParameters();
            permParams.setSendingPage(-1L);
            createStandardToolBarLink(PermissionsHelperProducer.VIEW_ID, tofill, "callpermissions",
                    "simplepage.permissions", permParams, "simplepage.permissions.tooltip");

        }

        // in any case, tell them they can't read the page
        UIOutput.make(tofill, "error-div");
        UIOutput.make(tofill, "error", messageLocator.getMessage("simplepage.nopermissions"));
        return;
    }

    String addBefore = params.getAddBefore();
    if (params.addTool == GeneralViewParameters.COMMENTS) {
        simplePageBean.addCommentsSection(addBefore);
    } else if (params.addTool == GeneralViewParameters.STUDENT_CONTENT) {
        simplePageBean.addStudentContentSection(addBefore);
    } else if (params.addTool == GeneralViewParameters.STUDENT_PAGE) {
        simplePageBean.createStudentPage(params.studentItemId);
        canEditPage = simplePageBean.canEditPage();
    }

    // Find the MSIE version, if we're running it.
    int ieVersion = checkIEVersion();
    // as far as I can tell, none of these supports fck or ck
    // we can make it configurable if necessary, or use WURFL
    // however this test is consistent with CKeditor's check.
    // that desireable, since if CKeditor is going to use a bare
    // text block, we want to handle it as noEditor
    String userAgent = httpServletRequest.getHeader("User-Agent");
    if (userAgent == null)
        userAgent = "";
    boolean noEditor = userAgent.toLowerCase().indexOf("mobile") >= 0;

    // set up locale
    Locale M_locale = null;
    String langLoc[] = localegetter.get().toString().split("_");
    if (langLoc.length >= 2) {
        if ("en".equals(langLoc[0]) && "ZA".equals(langLoc[1])) {
            M_locale = new Locale("en", "GB");
        } else {
            M_locale = new Locale(langLoc[0], langLoc[1]);
        }
    } else {
        M_locale = new Locale(langLoc[0]);
    }

    // clear session attribute if necessary, after calling Samigo
    String clearAttr = params.getClearAttr();

    if (clearAttr != null && !clearAttr.equals("")) {
        Session session = SessionManager.getCurrentSession();
        // don't let users clear random attributes
        if (clearAttr.startsWith("LESSONBUILDER_RETURNURL")) {
            session.setAttribute(clearAttr, null);
        }
    }

    if (htmlTypes == null) {
        String mmTypes = ServerConfigurationService.getString("lessonbuilder.html.types", DEFAULT_HTML_TYPES);
        htmlTypes = mmTypes.split(",");
        for (int i = 0; i < htmlTypes.length; i++) {
            htmlTypes[i] = htmlTypes[i].trim().toLowerCase();
        }
        Arrays.sort(htmlTypes);
    }

    if (mp4Types == null) {
        String m4Types = ServerConfigurationService.getString("lessonbuilder.mp4.types", DEFAULT_MP4_TYPES);
        mp4Types = m4Types.split(",");
        for (int i = 0; i < mp4Types.length; i++) {
            mp4Types[i] = mp4Types[i].trim().toLowerCase();
        }
        Arrays.sort(mp4Types);
    }

    if (html5Types == null) {
        String jTypes = ServerConfigurationService.getString("lessonbuilder.html5.types", DEFAULT_HTML5_TYPES);
        html5Types = jTypes.split(",");
        for (int i = 0; i < html5Types.length; i++) {
            html5Types[i] = html5Types[i].trim().toLowerCase();
        }
        Arrays.sort(html5Types);
    }

    // remember that page tool was reset, so we need to give user the option
    // of going to the last page from the previous session
    SimplePageToolDao.PageData lastPage = simplePageBean.toolWasReset();

    // if this page was copied from another site we may have to update links
    // can only do the fixups if you can write. We could hack permissions, but
    // I assume a site owner will access the site first
    if (canEditPage)
        simplePageBean.maybeUpdateLinks();

    // if starting the tool, sendingpage isn't set. the following call
    // will give us the top page.
    SimplePage currentPage = simplePageBean.getCurrentPage();

    // now we need to find our own item, for access checks, etc.
    SimplePageItem pageItem = null;
    if (currentPage != null) {
        pageItem = simplePageBean.getCurrentPageItem(params.getItemId());
    }
    // one more security check: make sure the item actually involves this
    // page.
    // otherwise someone could pass us an item from a different page in
    // another site
    // actually this normally happens if the page doesn't exist and we don't
    // have permission to create it
    if (currentPage == null || pageItem == null || (pageItem.getType() != SimplePageItem.STUDENT_CONTENT
            && Long.valueOf(pageItem.getSakaiId()) != currentPage.getPageId())) {
        log.warn("ShowPage item not in page");
        UIOutput.make(tofill, "error-div");
        if (currentPage == null)
            // most likely tool was created by site info but no page
            // has created. It will created the first time an item is created,
            // so from a user point of view it looks like no item has been added
            UIOutput.make(tofill, "error", messageLocator.getMessage("simplepage.noitems_error_user"));
        else
            UIOutput.make(tofill, "error", messageLocator.getMessage("simplepage.not_available"));
        return;
    }

    // the reason for a seaprate release date test is so we can show the date.
    // there are currently some issues. If the page is not released and the user doesn't have
    // access because of groups, this will show the not released data. That's misleading because
    // when the release date comes the user still won't be able to see it. Not sure if it's worth
    // creating a separate function that just checks the groups. It's easy to test hidden, so I do that. The idea is that
    // if it's both hidden and not released it makes sense to show hidden.

    // check two parts of isitemvisible where we want to give specific errors
    // potentially need time zone for setting release date
    if (!canSeeAll && currentPage.getReleaseDate() != null && currentPage.getReleaseDate().after(new Date())
            && !currentPage.isHidden()) {
        DateFormat df = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.SHORT, M_locale);
        TimeZone tz = timeService.getLocalTimeZone();
        df.setTimeZone(tz);
        String releaseDate = df.format(currentPage.getReleaseDate());
        String releaseMessage = messageLocator.getMessage("simplepage.not_yet_available_releasedate")
                .replace("{}", releaseDate);

        UIOutput.make(tofill, "error-div");
        UIOutput.make(tofill, "error", releaseMessage);

        return;
    }

    // the only thing not already tested (or tested in release check below) in isItemVisible is groups. In theory
    // no one should have a URL to a page for which they aren't in the group,
    // so I'm not trying to give a better message than just hidden
    if (!canSeeAll && currentPage.isHidden() || !simplePageBean.isItemVisible(pageItem)) {
        UIOutput.make(tofill, "error-div");
        UIOutput.make(tofill, "error", messageLocator.getMessage("simplepage.not_available_hidden"));
        return;
    }

    // I believe we've now checked all the args for permissions issues. All
    // other item and
    // page references are generated here based on the contents of the page
    // and items.

    // needed to process path arguments first, so refresh page goes the right page
    if (simplePageBean.getTopRefresh()) {
        UIOutput.make(tofill, "refresh");
        return; // but there's no point doing anything more
    }

    // error from previous operation
    // consumes the message, so don't do it if refreshing
    List<String> errMessages = simplePageBean.errMessages();
    if (errMessages != null) {
        UIOutput.make(tofill, "error-div");
        for (String e : errMessages) {
            UIBranchContainer er = UIBranchContainer.make(tofill, "errors:");
            UIOutput.make(er, "error-message", e);
        }
    }

    if (canEditPage) {
        // special instructor-only javascript setup.
        // but not if we're refreshing
        UIOutput.make(tofill, "instructoronly");
        // Chome and IE will abort a page if some on it was input from
        // a previous submit. I.e. if an HTML editor was used. In theory they
        // only do this if part of it is Javascript, but in practice they do
        // it for images as well. The protection isn't worthwhile, since it only
        // protects the first time. Since it will reesult in a garbled page, 
        // people will just refresh the page, and then they'll get the new
        // contents. The Chrome guys refuse to fix this so it just applies to Javascript
        httpServletResponse.setHeader("X-XSS-Protection", "0");
    }

    if (currentPage == null || pageItem == null) {
        UIOutput.make(tofill, "error-div");
        if (canEditPage) {
            UIOutput.make(tofill, "error", messageLocator.getMessage("simplepage.impossible1"));
        } else {
            UIOutput.make(tofill, "error", messageLocator.getMessage("simplepage.not_available"));
        }
        return;
    }

    // Set up customizable CSS
    ContentResource cssLink = simplePageBean.getCssForCurrentPage();
    if (cssLink != null) {
        UIOutput.make(tofill, "customCSS").decorate(new UIFreeAttributeDecorator("href", cssLink.getUrl()));
    }

    // offer to go to saved page if this is the start of a session, in case
    // user has logged off and logged on again.
    // need to offer to go to previous page? even if a new session, no need
    // if we're already on that page
    if (lastPage != null && lastPage.pageId != currentPage.getPageId()) {
        UIOutput.make(tofill, "refreshAlert");
        UIOutput.make(tofill, "refresh-message", messageLocator.getMessage("simplepage.last-visited"));
        // Should simply refresh
        GeneralViewParameters p = new GeneralViewParameters(VIEW_ID);
        p.setSendingPage(lastPage.pageId);
        p.setItemId(lastPage.itemId);
        // reset the path to the saved one
        p.setPath("log");

        String name = lastPage.name;

        // Titles are set oddly by Student Content Pages
        SimplePage lastPageObj = simplePageToolDao.getPage(lastPage.pageId);
        if (lastPageObj.getOwner() != null) {
            name = lastPageObj.getTitle();
        }

        UIInternalLink.make(tofill, "refresh-link", name, p);
    }

    // path is the breadcrumbs. Push, pop or reset depending upon path=
    // programmer documentation.
    String title;
    String ownerName = null;
    if (pageItem.getType() != SimplePageItem.STUDENT_CONTENT) {
        title = pageItem.getName();
    } else {
        title = currentPage.getTitle();
        if (!pageItem.isAnonymous() || canEditPage) {
            try {
                String owner = currentPage.getOwner();
                String group = currentPage.getGroup();
                if (group != null)
                    ownerName = simplePageBean.getCurrentSite().getGroup(group).getTitle();
                else
                    ownerName = UserDirectoryService.getUser(owner).getDisplayName();

            } catch (Exception ignore) {
            }
            ;
            if (ownerName != null && !ownerName.equals(title))
                title += " (" + ownerName + ")";
        }
    }

    String newPath = null;

    // If the path is "none", then we don't want to record this page as being viewed, or set a path
    if (!params.getPath().equals("none")) {
        newPath = simplePageBean.adjustPath(params.getPath(), currentPage.getPageId(), pageItem.getId(), title);
        simplePageBean.adjustBackPath(params.getBackPath(), currentPage.getPageId(), pageItem.getId(),
                pageItem.getName());
    }

    // put out link to index of pages
    GeneralViewParameters showAll = new GeneralViewParameters(PagePickerProducer.VIEW_ID);
    showAll.setSource("summary");
    UIInternalLink.make(tofill, "print-view", messageLocator.getMessage("simplepage.print_view"), showAll);
    UIInternalLink.make(tofill, "show-pages", messageLocator.getMessage("simplepage.showallpages"), showAll);

    if (canEditPage) {
        // show tool bar, but not if coming from grading pane
        if (!cameFromGradingPane) {
            createToolBar(tofill, currentPage, (pageItem.getType() == SimplePageItem.STUDENT_CONTENT));
        }

        UIOutput.make(tofill, "title-descrip");
        String label = null;
        if (pageItem.getType() == SimplePageItem.STUDENT_CONTENT)
            label = messageLocator.getMessage("simplepage.editTitle");
        else
            label = messageLocator.getMessage("simplepage.title");
        String descrip = null;
        if (pageItem.getType() == SimplePageItem.STUDENT_CONTENT)
            descrip = messageLocator.getMessage("simplepage.title-student-descrip");
        else if (pageItem.getPageId() == 0)
            descrip = messageLocator.getMessage("simplepage.title-top-descrip");
        else
            descrip = messageLocator.getMessage("simplepage.title-descrip");

        UIOutput.make(tofill, "edit-title").decorate(new UIFreeAttributeDecorator("title", descrip));
        UIOutput.make(tofill, "edit-title-text", label);
        UIOutput.make(tofill, "title-descrip-text", descrip);

        if (pageItem.getPageId() == 0 && currentPage.getOwner() == null) { // top level page
            // need dropdown 
            UIOutput.make(tofill, "dropdown");
            UIOutput.make(tofill, "moreDiv");
            UIOutput.make(tofill, "new-page").decorate(new UIFreeAttributeDecorator("title",
                    messageLocator.getMessage("simplepage.new-page-tooltip")));
            createToolBarLink(PermissionsHelperProducer.VIEW_ID, tofill, "permissions",
                    "simplepage.permissions", currentPage, "simplepage.permissions.tooltip");
            UIOutput.make(tofill, "import-cc").decorate(new UIFreeAttributeDecorator("title",
                    messageLocator.getMessage("simplepage.import_cc.tooltip")));
            UIOutput.make(tofill, "export-cc").decorate(new UIFreeAttributeDecorator("title",
                    messageLocator.getMessage("simplepage.export_cc.tooltip")));

            // Check to see if we have tools registered for external import
            List<Map<String, Object>> toolsFileItem = simplePageBean.getToolsFileItem();
            if (toolsFileItem.size() > 0) {
                UIOutput.make(tofill, "show-lti-import");
                UIForm ltiImport = UIForm.make(tofill, "lti-import-form");
                makeCsrf(ltiImport, "csrf1");
                GeneralViewParameters ltiParams = new GeneralViewParameters();
                ltiParams.setSendingPage(currentPage.getPageId());
                ltiParams.viewID = LtiFileItemProducer.VIEW_ID;
                UILink link = UIInternalLink.make(tofill, "lti-import-link",
                        messageLocator.getMessage("simplepage.import_lti_button"), ltiParams);
                link.decorate(new UITooltipDecorator(messageLocator.getMessage("simplepage.fileitem.tooltip")));
            }
        }

        // Checks to see that user can edit and that this is either a top level page,
        // or a top level student page (not a subpage to a student page)
        if (simplePageBean.getEditPrivs() == 0 && (pageItem.getPageId() == 0)) {
            UIOutput.make(tofill, "remove-li");
            UIOutput.make(tofill, "remove-page").decorate(new UIFreeAttributeDecorator("title",
                    messageLocator.getMessage("simplepage.remove-page-tooltip")));

            if (allowDeleteOrphans) {
                UIOutput.make(tofill, "delete-orphan-li");
                UIForm orphan = UIForm.make(tofill, "delete-orphan-form");
                makeCsrf(orphan, "csrf1");
                UICommand.make(orphan, "delete-orphan", "#{simplePageBean.deleteOrphanPages}");
                UIOutput.make(orphan, "delete-orphan-link").decorate(new UIFreeAttributeDecorator("title",
                        messageLocator.getMessage("simplepage.delete-orphan-pages-desc")));
            }

        } else if (simplePageBean.getEditPrivs() == 0 && currentPage.getOwner() != null) {
            // getEditPrivs < 2 if we want to let the student delete. Currently we don't. There can be comments
            // from other students and the page can be shared
            SimpleStudentPage studentPage = simplePageToolDao.findStudentPage(currentPage.getTopParent());
            if (studentPage != null && studentPage.getPageId() == currentPage.getPageId()) {
                UIOutput.make(tofill, "remove-student");
                UIOutput.make(tofill, "remove-page-student").decorate(new UIFreeAttributeDecorator("title",
                        messageLocator.getMessage("simplepage.remove-student-page-explanation")));
            }
        }

        UIOutput.make(tofill, "dialogDiv");
        UIOutput.make(tofill, "siteid", simplePageBean.getCurrentSiteId());
        UIOutput.make(tofill, "locale", M_locale.toString());

    } else if (!canReadPage) {
        return;
    } else if (!canSeeAll) {
        // see if there are any unsatisfied prerequisites
        // if this isn't a top level page, this will check that the page above is
        // accessible. That matters because we check visible, available and release
        // only for this page but not for the containing page
        List<String> needed = simplePageBean.pagesNeeded(pageItem);
        if (needed.size() > 0) {
            // yes. error and abort
            if (pageItem.getPageId() != 0) {
                // not top level. This should only happen from a "next"
                // link.
                // at any rate, the best approach is to send the user back
                // to the calling page
                List<SimplePageBean.PathEntry> path = simplePageBean.getHierarchy();
                SimplePageBean.PathEntry containingPage = null;
                if (path.size() > 1) {
                    // page above this. this page is on the top
                    containingPage = path.get(path.size() - 2);
                }

                if (containingPage != null) { // not a top level page, point
                    // to containing page
                    GeneralViewParameters view = new GeneralViewParameters(VIEW_ID);
                    view.setSendingPage(containingPage.pageId);
                    view.setItemId(containingPage.pageItemId);
                    view.setPath(Integer.toString(path.size() - 2));
                    UIInternalLink.make(tofill, "redirect-link", containingPage.title, view);
                    UIOutput.make(tofill, "redirect");
                } else {
                    UIOutput.make(tofill, "error-div");
                    UIOutput.make(tofill, "error", messageLocator.getMessage("simplepage.not_available"));
                }

                return;
            }

            // top level page where prereqs not satisified. Output list of
            // pages he needs to do first
            UIOutput.make(tofill, "pagetitle", currentPage.getTitle());
            UIOutput.make(tofill, "error-div");
            UIOutput.make(tofill, "error", messageLocator.getMessage("simplepage.has_prerequistes"));
            UIBranchContainer errorList = UIBranchContainer.make(tofill, "error-list:");
            for (String errorItem : needed) {
                UIBranchContainer errorListItem = UIBranchContainer.make(errorList, "error-item:");
                UIOutput.make(errorListItem, "error-item-text", errorItem);
            }
            return;
        }
    }

    ToolSession toolSession = SessionManager.getCurrentToolSession();
    // this code is now for 11 only. helpurl is used in 9 and 10 to indicate neo portal
    // at this point only two code paths are intended to work. inline and iframe.
    // inline pushes stuff into the morpheus-generated header. iframe uses an extra line
    // the previous mode required us to try to duplicate the header generated by morpheus
    // this was too error-prone.
    String helpurl = null; /* (String)toolSession.getAttribute("sakai-portal:help-action"); */
    String reseturl = null; /* (String)toolSession.getAttribute("sakai-portal:reset-action"); */

    Placement placement = toolManager.getCurrentPlacement();
    String toolId = placement.getToolId();
    boolean inline = false;

    // inline includes iframes when morpheus is in effect
    if ("morpheus".equals(portalTemplates) && httpServletRequest.getRequestURI().startsWith("/portal/site/")) {
        inline = true;
    }

    String skinName = null;
    String skinRepo = null;
    String iconBase = null;

    UIComponent titlediv = UIOutput.make(tofill, "titlediv");
    if (inline)
        titlediv.decorate(new UIFreeAttributeDecorator("style", "display:none"));
    // we need to do special CSS for old portal
    else if (helpurl == null)
        titlediv.decorate(new UIStyleDecorator("oldPortal"));

    if (helpurl != null || reseturl != null) {
        // these URLs are defined if we're in the neo portal
        // in that case we need our own help and reset icons. We want
        // to take them from the current skin, so find its prefix.
        // unfortunately the neoportal tacks neo- on front of the skin
        // name, so this is more complex than you might think.

        skinRepo = ServerConfigurationService.getString("skin.repo", "/library/skin");
        iconBase = skinRepo + "/" + CSSUtils.adjustCssSkinFolder(null) + "/images";

        UIVerbatim.make(tofill, "iconstyle", ICONSTYLE.replace("{}", iconBase));

    }

    if (helpurl != null) {
        UILink.make(tofill, (pageItem.getPageId() == 0 ? "helpbutton" : "helpbutton2"), helpurl)
                .decorate(new UIFreeAttributeDecorator("onclick", "openWindow('" + helpurl
                        + "', 'Help', 'resizeable=yes,toolbar=no,scrollbars=yes,menubar=yes,width=800,height=600'); return false"))
                .decorate(new UIFreeAttributeDecorator("title",
                        messageLocator.getMessage("simplepage.help-button")));
        if (!inline)
            UIOutput.make(tofill, (pageItem.getPageId() == 0 ? "helpimage" : "helpimage2")).decorate(
                    new UIFreeAttributeDecorator("alt", messageLocator.getMessage("simplepage.help-button")));
        UIOutput.make(tofill, (pageItem.getPageId() == 0 ? "helpnewwindow" : "helpnewwindow2"),
                messageLocator.getMessage("simplepage.opens-in-new"));
        UILink.make(tofill, "directurl")
                .decorate(new UIFreeAttributeDecorator("rel",
                        "#Main" + Web.escapeJavascript(placement.getId()) + "_directurl"))
                .decorate(new UIFreeAttributeDecorator("title",
                        messageLocator.getMessage("simplepage.direct-link")));
        // if (inline) {
        UIOutput.make(tofill, "directurl-div").decorate(new UIFreeAttributeDecorator("id",
                "Main" + Web.escapeJavascript(placement.getId()) + "_directurl"));
        // in general 2.9 doesn't have the url shortener
        if (majorVersion >= 10) {
            UIOutput.make(tofill, "directurl-input")
                    .decorate(new UIFreeAttributeDecorator("onclick",
                            "toggleShortUrlOutput('" + myUrl() + "/portal/directtool/" + placement.getId()
                                    + "/', this, 'Main" + Web.escapeJavascript(placement.getId())
                                    + "_urlholder');"));
            UIOutput.make(tofill, "directurl-shorten", messageLocator.getMessage("simplepage.short-url"));
        }
        UIOutput.make(tofill, "directurl-textarea", myUrl() + "/portal/directtool/" + placement.getId() + "/")
                .decorate(new UIFreeAttributeDecorator("class",
                        "portlet title-tools Main" + Web.escapeJavascript(placement.getId()) + "_urlholder"));
        // } else
        UIOutput.make(tofill, "directimage").decorate(
                new UIFreeAttributeDecorator("alt", messageLocator.getMessage("simplepage.direct-link")));
    }

    // morpheus does reset as part of title
    if (reseturl != null && !inline) {
        UILink.make(tofill, (pageItem.getPageId() == 0 ? "resetbutton" : "resetbutton2"), reseturl)
                .decorate(new UIFreeAttributeDecorator("onclick",
                        "location.href='" + reseturl + "'; return false"))
                .decorate(new UIFreeAttributeDecorator("title",
                        messageLocator.getMessage("simplepage.reset-button")));
        UIOutput.make(tofill, (pageItem.getPageId() == 0 ? "resetimage" : "resetimage2")).decorate(
                new UIFreeAttributeDecorator("alt", messageLocator.getMessage("simplepage.reset-button")));
    }

    // note page accessed. the code checks to see whether all the required
    // items on it have been finished, and if so marks it complete, else just updates
    // access date save the path because if user goes to it later we want to restore the
    // breadcrumbs
    if (newPath != null) {
        if (pageItem.getType() != SimplePageItem.STUDENT_CONTENT) {
            simplePageBean.track(pageItem.getId(), newPath);
        } else {
            simplePageBean.track(pageItem.getId(), newPath, currentPage.getPageId());
        }
    }

    if (currentPage.getOwner() != null && simplePageBean.getEditPrivs() == 0) {
        SimpleStudentPage student = simplePageToolDao.findStudentPageByPageId(currentPage.getPageId());

        // Make sure this is a top level student page
        if (student != null && pageItem.getGradebookId() != null) {
            UIOutput.make(tofill, "gradingSpan");
            UIOutput.make(tofill, "commentsUUID", String.valueOf(student.getId()));
            UIOutput.make(tofill, "commentPoints",
                    String.valueOf((student.getPoints() != null ? student.getPoints() : "")));
            UIOutput pointsBox = UIOutput.make(tofill, "studentPointsBox");
            UIOutput.make(tofill, "topmaxpoints", String
                    .valueOf((pageItem.getGradebookPoints() != null ? pageItem.getGradebookPoints() : "")));
            if (ownerName != null)
                pointsBox.decorate(new UIFreeAttributeDecorator("title",
                        messageLocator.getMessage("simplepage.grade-for-student").replace("{}", ownerName)));

            List<SimpleStudentPage> studentPages = simplePageToolDao.findStudentPages(student.getItemId());

            Collections.sort(studentPages, new Comparator<SimpleStudentPage>() {
                public int compare(SimpleStudentPage o1, SimpleStudentPage o2) {
                    String title1 = o1.getTitle();
                    if (title1 == null)
                        title1 = "";
                    String title2 = o2.getTitle();
                    if (title2 == null)
                        title2 = "";
                    return title1.compareTo(title2);
                }
            });

            for (int in = 0; in < studentPages.size(); in++) {
                if (studentPages.get(in).isDeleted()) {
                    studentPages.remove(in);
                }
            }

            int i = -1;

            for (int in = 0; in < studentPages.size(); in++) {
                if (student.getId() == studentPages.get(in).getId()) {
                    i = in;
                    break;
                }
            }

            if (i > 0) {
                GeneralViewParameters eParams = new GeneralViewParameters(ShowPageProducer.VIEW_ID,
                        studentPages.get(i - 1).getPageId());
                eParams.setItemId(studentPages.get(i - 1).getItemId());
                eParams.setPath("next");

                UIInternalLink.make(tofill, "gradingBack", eParams);
            }

            if (i < studentPages.size() - 1) {
                GeneralViewParameters eParams = new GeneralViewParameters(ShowPageProducer.VIEW_ID,
                        studentPages.get(i + 1).getPageId());
                eParams.setItemId(studentPages.get(i + 1).getItemId());
                eParams.setPath("next");

                UIInternalLink.make(tofill, "gradingForward", eParams);
            }

            printGradingForm(tofill);
        }
    }

    // breadcrumbs
    if (pageItem.getPageId() != 0) {
        // Not top-level, so we have to show breadcrumbs

        List<SimplePageBean.PathEntry> breadcrumbs = simplePageBean.getHierarchy();

        int index = 0;
        if (breadcrumbs.size() > 1 || reseturl != null || helpurl != null) {
            UIOutput.make(tofill, "crumbdiv");
            if (breadcrumbs.size() > 1)
                for (SimplePageBean.PathEntry e : breadcrumbs) {
                    // don't show current page. We already have a title. This
                    // was too much
                    UIBranchContainer crumb = UIBranchContainer.make(tofill, "crumb:");
                    GeneralViewParameters view = new GeneralViewParameters(VIEW_ID);
                    view.setSendingPage(e.pageId);
                    view.setItemId(e.pageItemId);
                    view.setPath(Integer.toString(index));
                    UIComponent link = null;
                    if (index < breadcrumbs.size() - 1) {
                        // Not the last item
                        link = UIInternalLink.make(crumb, "crumb-link", e.title, view);
                        UIOutput.make(crumb, "crumb-follow", " > ");
                    } else {
                        UIOutput.make(crumb, "crumb-follow", e.title).decorate(new UIStyleDecorator("bold"));
                    }
                    index++;
                }
            else {
                UIBranchContainer crumb = UIBranchContainer.make(tofill, "crumb:");
                UILink.make(crumb, "crum-link", currentPage.getTitle(), reseturl);
            }
        } else {
            if (reseturl != null) {
                UIOutput.make(tofill, "pagetitletext", currentPage.getTitle());
            } else if (!inline) {
                UIOutput.make(tofill, "pagetitle", currentPage.getTitle());
            }
        }
    } else {
        if (reseturl != null) {
            UILink.make(tofill, "pagetitlelink", reseturl);
            UIOutput.make(tofill, "pagetitletext", currentPage.getTitle());
        } else if (!inline) {
            UIOutput.make(tofill, "pagetitle", currentPage.getTitle());
        }
    }

    // see if there's a next item in sequence.
    simplePageBean.addPrevLink(tofill, pageItem);
    simplePageBean.addNextLink(tofill, pageItem);

    // swfObject is not currently used
    boolean shownSwfObject = false;

    long newItemId = -1L;
    String newItemStr = (String) toolSession.getAttribute("lessonbuilder.newitem");
    if (newItemStr != null) {
        toolSession.removeAttribute("lessonbuilder.newitem");
        try {
            newItemId = Long.parseLong(newItemStr);
        } catch (Exception e) {
        }
    }

    // items to show
    List<SimplePageItem> itemList = (List<SimplePageItem>) simplePageBean
            .getItemsOnPage(currentPage.getPageId());

    // Move all items with sequence <= 0 to the end of the list.
    // Count is necessary to guarantee we don't infinite loop over a
    // list that only has items with sequence <= 0.
    // Becauses sequence number is < 0, these start out at the beginning
    int count = 1;
    while (itemList.size() > count && itemList.get(0).getSequence() <= 0) {
        itemList.add(itemList.remove(0));
        count++;
    }

    // Make sure we only add the comments javascript file once,
    // even if there are multiple comments tools on the page.
    boolean addedCommentsScript = false;
    int commentsCount = 0;

    // Find the most recent comment on the page by current user
    long postedCommentId = -1;
    if (params.postedComment) {
        postedCommentId = findMostRecentComment();
    }

    boolean showDownloads = (simplePageBean.getCurrentSite().getProperties()
            .getProperty("lessonbuilder-nodownloadlinks") == null);

    //
    //
    // MAIN list of items
    //
    // produce the main table

    // Is anything visible?
    // Note that we don't need to check whether any item is available, since the first visible
    // item is always available.
    boolean anyItemVisible = false;

    if (itemList.size() > 0) {
        UIBranchContainer container = UIBranchContainer.make(tofill, "itemContainer:");

        boolean showRefresh = false;
        boolean fisrt = false;
        int textboxcount = 1;

        int cols = 0;
        int colnum = 0;

        UIBranchContainer sectionContainer = null;
        UIBranchContainer columnContainer = null;
        UIBranchContainer tableContainer = null;

        boolean first = true;

        for (SimplePageItem i : itemList) {

            // break is not a normal item. handle it first
            // this will work whether first item is break or not. Might be a section
            // break or a normal item
            if (first || i.getType() == SimplePageItem.BREAK) {
                boolean sectionbreak = false;
                if (first || "section".equals(i.getFormat())) {
                    sectionContainer = UIBranchContainer.make(container, "section:");
                    cols = colCount(itemList, i.getId());
                    sectionbreak = true;
                    colnum = 0;
                } else if ("colunn".equals(i.getFormat()))
                    colnum++;
                columnContainer = UIBranchContainer.make(sectionContainer, "column:");

                tableContainer = UIBranchContainer.make(columnContainer, "itemTable:");
                Integer width = new Integer(
                        i.getAttribute("colwidth") == null ? "1" : i.getAttribute("colwidth"));
                Integer split = new Integer(
                        i.getAttribute("colsplit") == null ? "1" : i.getAttribute("colsplit"));
                colnum += width; // number after this column

                String color = i.getAttribute("colcolor");

                columnContainer.decorate(new UIStyleDecorator(
                        "cols" + cols + (colnum == cols ? " lastcol" : "") + (width > 1 ? " double" : "")
                                + (split > 1 ? " split" : "") + (color == null ? "" : " col" + color)));
                UIComponent delIcon = UIOutput.make(columnContainer, "section-td");
                if (first)
                    delIcon.decorate(new UIFreeAttributeDecorator("style", "display:none"));

                UIOutput.make(columnContainer, "break-msg", messageLocator
                        .getMessage(sectionbreak ? "simplepage.break-here" : "simplepage.break-column-here"));
                UIOutput.make(columnContainer, "section2");
                UIOutput.make(columnContainer, "section3").decorate(new UIFreeAttributeDecorator("title",
                        messageLocator.getMessage("simplepage.columnopen")));
                UIOutput.make(columnContainer, "addbottom");
                UIOutput.make(columnContainer, "addbottom2").decorate(new UIFreeAttributeDecorator("title",
                        messageLocator.getMessage("simplepage.add-item-column")));
                UILink link = UILink.make(columnContainer, "section-del-link", (String) null, "/" + i.getId());
                link.decorate(new UIFreeAttributeDecorator("title",
                        messageLocator.getMessage("simplepage.join-items")));
                link.decorate(new UIStyleDecorator(sectionbreak ? "section-merge-link" : "column-merge-link"));

                UIBranchContainer tableRow = UIBranchContainer.make(tableContainer, "item:");
                tableRow.decorate(new UIFreeAttributeDecorator("class", "break" + i.getFormat()));

                first = false;
                if (i.getType() == SimplePageItem.BREAK)
                    continue;
                // for first item, if wasn't break, process it
            }

            // listitem is mostly historical. it uses some shared HTML, but
            // if I were
            // doing it from scratch I wouldn't make this distinction. At
            // the moment it's
            // everything that isn't inline.

            boolean listItem = !(i.getType() == SimplePageItem.TEXT || i.getType() == SimplePageItem.MULTIMEDIA
                    || i.getType() == SimplePageItem.COMMENTS || i.getType() == SimplePageItem.STUDENT_CONTENT
                    || i.getType() == SimplePageItem.QUESTION || i.getType() == SimplePageItem.PEEREVAL
                    || i.getType() == SimplePageItem.BREAK);
            // (i.getType() == SimplePageItem.PAGE &&
            // "button".equals(i.getFormat())))

            if (!simplePageBean.isItemVisible(i, currentPage)) {
                continue;
            }
            // break isn't a real item. probably don't want to count it
            if (i.getType() != SimplePageItem.BREAK)
                anyItemVisible = true;

            UIBranchContainer tableRow = UIBranchContainer.make(tableContainer, "item:");

            // set class name showing what the type is, so people can do funky CSS

            String itemClassName = null;

            switch (i.getType()) {
            case SimplePageItem.RESOURCE:
                itemClassName = "resourceType";
                break;
            case SimplePageItem.PAGE:
                itemClassName = "pageType";
                break;
            case SimplePageItem.ASSIGNMENT:
                itemClassName = "assignmentType";
                break;
            case SimplePageItem.ASSESSMENT:
                itemClassName = "assessmentType";
                break;
            case SimplePageItem.TEXT:
                itemClassName = "textType";
                break;
            case SimplePageItem.URL:
                itemClassName = "urlType";
                break;
            case SimplePageItem.MULTIMEDIA:
                itemClassName = "multimediaType";
                break;
            case SimplePageItem.FORUM:
                itemClassName = "forumType";
                break;
            case SimplePageItem.COMMENTS:
                itemClassName = "commentsType";
                break;
            case SimplePageItem.STUDENT_CONTENT:
                itemClassName = "studentContentType";
                break;
            case SimplePageItem.QUESTION:
                itemClassName = "question";
                break;
            case SimplePageItem.BLTI:
                itemClassName = "bltiType";
                break;
            case SimplePageItem.PEEREVAL:
                itemClassName = "peereval";
                break;
            }

            if (listItem) {
                itemClassName = itemClassName + " listType";
            }
            if (canEditPage) {
                itemClassName = itemClassName + "  canEdit";
            }

            if (i.getId() == newItemId)
                itemClassName = itemClassName + " newItem";

            tableRow.decorate(new UIFreeAttributeDecorator("class", itemClassName));

            if (canEditPage)
                UIOutput.make(tableRow, "itemid", String.valueOf(i.getId()));

            // you really need the HTML file open at the same time to make
            // sense of the following code
            if (listItem) { // Not an HTML Text, Element or Multimedia
                // Element

                if (canEditPage) {
                    UIOutput.make(tableRow, "current-item-id2", String.valueOf(i.getId()));
                }

                // users can declare a page item to be navigational. If so
                // we display
                // it to the left of the normal list items, and use a
                // button. This is
                // used for pages that are "next" pages, i.e. they replace
                // this page
                // rather than creating a new level in the breadcrumbs.
                // Since they can't
                // be required, they don't need the status image, which is
                // good because
                // they're displayed with colspan=2, so there's no space for
                // the image.

                boolean navButton = "button".equals(i.getFormat()) && !i.isRequired();
                boolean notDone = false;
                Status status = Status.NOT_REQUIRED;
                if (!navButton) {
                    status = handleStatusImage(tableRow, i);
                    if (status == Status.REQUIRED) {
                        notDone = true;
                    }
                }

                boolean isInline = (i.getType() == SimplePageItem.BLTI && "inline".equals(i.getFormat()));

                UIOutput linktd = UIOutput.make(tableRow, "item-td");

                UIOutput contentCol = UIOutput.make(tableRow, "contentCol");
                // BLTI seems to require explicit specificaiton for column width. Otherwise
                // we get 300 px wide. Don't know why. Doesn't happen to other iframes
                if (isInline)
                    contentCol.decorate(new UIFreeAttributeDecorator("style", "width:100%"));

                UIBranchContainer linkdiv = null;
                if (!isInline) {
                    linkdiv = UIBranchContainer.make(tableRow, "link-div:");
                    UIOutput itemicon = UIOutput.make(linkdiv, "item-icon");
                    switch (i.getType()) {
                    case SimplePageItem.FORUM:
                        itemicon.decorate(new UIStyleDecorator("fa-comments"));
                        break;
                    case SimplePageItem.ASSIGNMENT:
                        itemicon.decorate(new UIStyleDecorator("fa-tasks"));
                        break;
                    case SimplePageItem.ASSESSMENT:
                        itemicon.decorate(new UIStyleDecorator("fa-puzzle-piece"));
                        break;
                    case SimplePageItem.BLTI:
                        itemicon.decorate(new UIStyleDecorator("fa-globe"));
                        break;
                    case SimplePageItem.PAGE:
                        itemicon.decorate(new UIStyleDecorator("fa-folder-open-o"));
                        break;
                    case SimplePageItem.RESOURCE:
                        String mimeType = i.getHtml();

                        if ("application/octet-stream".equals(mimeType)) {
                            // OS X reports octet stream for things like MS Excel documents.
                            // Force a mimeType lookup so we get a decent icon.
                            mimeType = null;
                        }

                        if (mimeType == null || mimeType.equals("")) {
                            String s = i.getSakaiId();
                            int j = s.lastIndexOf(".");
                            if (j >= 0)
                                s = s.substring(j + 1);
                            mimeType = ContentTypeImageService.getContentType(s);
                            // System.out.println("type " + s + ">" + mimeType);
                        }

                        String src = null;
                        //if (!useSakaiIcons)
                        src = imageToMimeMap.get(mimeType);
                        if (src == null) {
                            src = "fa-file-o";
                            //String image = ContentTypeImageService.getContentTypeImage(mimeType);
                            // if (image != null)
                            //   src = "/library/image/" + image;
                        }

                        if (src != null) {
                            itemicon.decorate(new UIStyleDecorator(src));
                        }
                        break;
                    }
                }

                UIOutput descriptiondiv = null;

                // refresh isn't actually used anymore. We've changed the
                // way things are
                // done so the user never has to request a refresh.
                //   FYI: this actually puts in an IFRAME for inline BLTI items
                showRefresh = !makeLink(tableRow, "link", i, canSeeAll, currentPage, notDone, status)
                        || showRefresh;
                UILink.make(tableRow, "copylink", i.getName(),
                        "http://lessonbuilder.sakaiproject.org/" + i.getId() + "/")
                        .decorate(new UIFreeAttributeDecorator("title",
                                messageLocator.getMessage("simplepage.copylink2").replace("{}", i.getName())));

                // dummy is used when an assignment, quiz, or forum item is
                // copied
                // from another site. The way the copy code works, our
                // import code
                // doesn't have access to the necessary info to use the item
                // from the
                // new site. So we add a dummy, which generates an
                // explanation that the
                // author is going to have to choose the item from the
                // current site
                if (i.getSakaiId().equals(SimplePageItem.DUMMY)) {
                    String code = null;
                    switch (i.getType()) {
                    case SimplePageItem.ASSIGNMENT:
                        code = "simplepage.copied.assignment";
                        break;
                    case SimplePageItem.ASSESSMENT:
                        code = "simplepage.copied.assessment";
                        break;
                    case SimplePageItem.FORUM:
                        code = "simplepage.copied.forum";
                        break;
                    }
                    descriptiondiv = UIOutput.make(tableRow, "description", messageLocator.getMessage(code));
                } else {
                    descriptiondiv = UIOutput.make(tableRow, "description", i.getDescription());
                }
                if (isInline)
                    descriptiondiv.decorate(new UIFreeAttributeDecorator("style", "margin-top: 4px"));

                if (!isInline) {
                    // nav button gets float left so any description goes to its
                    // right. Otherwise the
                    // description block will display underneath
                    if ("button".equals(i.getFormat())) {
                        linkdiv.decorate(new UIFreeAttributeDecorator("style", "float:none"));
                    }
                    // for accessibility
                    if (navButton) {
                        linkdiv.decorate(new UIFreeAttributeDecorator("role", "navigation"));
                    }
                }

                // note that a lot of the info here is used by the
                // javascript that prepares
                // the jQuery dialogs
                String itemGroupString = null;
                boolean entityDeleted = false;
                boolean notPublished = false;
                if (canEditPage) {
                    UIOutput.make(tableRow, "edit-td");
                    UILink.make(tableRow, "edit-link", (String) null, "")
                            .decorate(new UIFreeAttributeDecorator("title", messageLocator
                                    .getMessage("simplepage.edit-title.generic").replace("{}", i.getName())));

                    // the following information is displayed using <INPUT
                    // type=hidden ...
                    // it contains information needed to populate the "edit"
                    // popup dialog
                    UIOutput.make(tableRow, "prerequisite-info", String.valueOf(i.isPrerequisite()));

                    if (i.getType() == SimplePageItem.ASSIGNMENT) {
                        // the type indicates whether scoring is letter
                        // grade, number, etc.
                        // the javascript needs this to present the right
                        // choices to the user
                        // types 6 and 8 aren't legal scoring types, so they
                        // are used as
                        // markers for quiz or forum. I ran out of numbers
                        // and started using
                        // text for things that aren't scoring types. That's
                        // better anyway
                        int type = 4;
                        LessonEntity assignment = null;
                        if (!i.getSakaiId().equals(SimplePageItem.DUMMY)) {
                            assignment = assignmentEntity.getEntity(i.getSakaiId(), simplePageBean);
                            if (assignment != null) {
                                type = assignment.getTypeOfGrade();
                                String editUrl = assignment.editItemUrl(simplePageBean);
                                if (editUrl != null) {
                                    UIOutput.make(tableRow, "edit-url", editUrl);
                                }
                                itemGroupString = simplePageBean.getItemGroupString(i, assignment, true);
                                UIOutput.make(tableRow, "item-groups", itemGroupString);
                                if (!assignment.objectExists())
                                    entityDeleted = true;
                                else if (assignment.notPublished())
                                    notPublished = true;
                            }
                        }

                        UIOutput.make(tableRow, "type", String.valueOf(type));
                        String requirement = String.valueOf(i.getSubrequirement());
                        if ((type == SimplePageItem.PAGE || type == SimplePageItem.ASSIGNMENT)
                                && i.getSubrequirement()) {
                            requirement = i.getRequirementText();
                        }
                        UIOutput.make(tableRow, "requirement-text", requirement);
                    } else if (i.getType() == SimplePageItem.ASSESSMENT) {
                        UIOutput.make(tableRow, "type", "6"); // Not used by
                        // assignments,
                        // so it is
                        // safe to dedicate to assessments
                        UIOutput.make(tableRow, "requirement-text",
                                (i.getSubrequirement() ? i.getRequirementText() : "false"));
                        LessonEntity quiz = quizEntity.getEntity(i.getSakaiId(), simplePageBean);
                        if (quiz != null) {
                            String editUrl = quiz.editItemUrl(simplePageBean);
                            if (editUrl != null) {
                                UIOutput.make(tableRow, "edit-url", editUrl);
                            }
                            editUrl = quiz.editItemSettingsUrl(simplePageBean);
                            if (editUrl != null) {
                                UIOutput.make(tableRow, "edit-settings-url", editUrl);
                            }
                            itemGroupString = simplePageBean.getItemGroupString(i, quiz, true);
                            UIOutput.make(tableRow, "item-groups", itemGroupString);
                            if (!quiz.objectExists())
                                entityDeleted = true;

                        } else
                            notPublished = quizEntity.notPublished(i.getSakaiId());
                    } else if (i.getType() == SimplePageItem.BLTI) {
                        UIOutput.make(tableRow, "type", "b");
                        LessonEntity blti = (bltiEntity == null ? null : bltiEntity.getEntity(i.getSakaiId()));
                        if (blti != null) {
                            String editUrl = blti.editItemUrl(simplePageBean);
                            if (editUrl != null)
                                UIOutput.make(tableRow, "edit-url", editUrl);
                            UIOutput.make(tableRow, "item-format", i.getFormat());

                            if (i.getHeight() != null)
                                UIOutput.make(tableRow, "item-height", i.getHeight());
                            itemGroupString = simplePageBean.getItemGroupString(i, null, true);
                            UIOutput.make(tableRow, "item-groups", itemGroupString);
                            if (!blti.objectExists())
                                entityDeleted = true;
                            else if (blti.notPublished())
                                notPublished = true;
                        }
                    } else if (i.getType() == SimplePageItem.FORUM) {
                        UIOutput.make(tableRow, "extra-info");
                        UIOutput.make(tableRow, "type", "8");
                        LessonEntity forum = forumEntity.getEntity(i.getSakaiId());
                        if (forum != null) {
                            String editUrl = forum.editItemUrl(simplePageBean);
                            if (editUrl != null) {
                                UIOutput.make(tableRow, "edit-url", editUrl);
                            }
                            itemGroupString = simplePageBean.getItemGroupString(i, forum, true);
                            UIOutput.make(tableRow, "item-groups", itemGroupString);
                            if (!forum.objectExists())
                                entityDeleted = true;
                            else if (forum.notPublished())
                                notPublished = true;

                        }
                    } else if (i.getType() == SimplePageItem.PAGE) {
                        UIOutput.make(tableRow, "type", "page");
                        UIOutput.make(tableRow, "page-next", Boolean.toString(i.getNextPage()));
                        UIOutput.make(tableRow, "page-button",
                                Boolean.toString("button".equals(i.getFormat())));
                        itemGroupString = simplePageBean.getItemGroupString(i, null, true);
                        UIOutput.make(tableRow, "item-groups", itemGroupString);
                    } else if (i.getType() == SimplePageItem.RESOURCE) {
                        try {
                            itemGroupString = simplePageBean.getItemGroupStringOrErr(i, null, true);
                        } catch (IdUnusedException e) {
                            itemGroupString = "";
                            entityDeleted = true;
                        }
                        if (simplePageBean.getInherited())
                            UIOutput.make(tableRow, "item-groups", "--inherited--");
                        else
                            UIOutput.make(tableRow, "item-groups", itemGroupString);
                        UIOutput.make(tableRow, "item-samewindow", Boolean.toString(i.isSameWindow()));

                        UIVerbatim.make(tableRow, "item-path", getItemPath(i));
                    }

                } // end of canEditPage

                if (canSeeAll) {
                    // haven't set up itemgroupstring yet
                    if (!canEditPage) {
                        if (!i.getSakaiId().equals(SimplePageItem.DUMMY)) {
                            LessonEntity lessonEntity = null;
                            switch (i.getType()) {
                            case SimplePageItem.ASSIGNMENT:
                                lessonEntity = assignmentEntity.getEntity(i.getSakaiId(), simplePageBean);
                                if (lessonEntity != null)
                                    itemGroupString = simplePageBean.getItemGroupString(i, lessonEntity, true);
                                if (!lessonEntity.objectExists())
                                    entityDeleted = true;
                                else if (lessonEntity.notPublished())
                                    notPublished = true;
                                break;
                            case SimplePageItem.ASSESSMENT:
                                lessonEntity = quizEntity.getEntity(i.getSakaiId(), simplePageBean);
                                if (lessonEntity != null)
                                    itemGroupString = simplePageBean.getItemGroupString(i, lessonEntity, true);
                                else
                                    notPublished = quizEntity.notPublished(i.getSakaiId());
                                if (!lessonEntity.objectExists())
                                    entityDeleted = true;
                                break;
                            case SimplePageItem.FORUM:
                                lessonEntity = forumEntity.getEntity(i.getSakaiId());
                                if (lessonEntity != null)
                                    itemGroupString = simplePageBean.getItemGroupString(i, lessonEntity, true);
                                if (!lessonEntity.objectExists())
                                    entityDeleted = true;
                                else if (lessonEntity.notPublished())
                                    notPublished = true;
                                break;
                            case SimplePageItem.BLTI:
                                if (bltiEntity != null)
                                    lessonEntity = bltiEntity.getEntity(i.getSakaiId());
                                if (lessonEntity != null)
                                    itemGroupString = simplePageBean.getItemGroupString(i, null, true);
                                if (!lessonEntity.objectExists())
                                    entityDeleted = true;
                                else if (lessonEntity.notPublished())
                                    notPublished = true;
                                break;
                            case SimplePageItem.PAGE:
                                itemGroupString = simplePageBean.getItemGroupString(i, null, true);
                                break;
                            case SimplePageItem.RESOURCE:
                                try {
                                    itemGroupString = simplePageBean.getItemGroupStringOrErr(i, null, true);
                                } catch (IdUnusedException e) {
                                    itemGroupString = "";
                                    entityDeleted = true;
                                }
                                break;
                            }
                        }
                    }

                    String releaseString = simplePageBean.getReleaseString(i);
                    if (itemGroupString != null || releaseString != null || entityDeleted || notPublished) {
                        if (itemGroupString != null)
                            itemGroupString = simplePageBean.getItemGroupTitles(itemGroupString, i);
                        if (itemGroupString != null) {
                            itemGroupString = " [" + itemGroupString + "]";
                            if (releaseString != null)
                                itemGroupString = " " + releaseString + itemGroupString;
                        } else if (releaseString != null)
                            itemGroupString = " " + releaseString;
                        if (notPublished) {
                            if (itemGroupString != null)
                                itemGroupString = itemGroupString + " "
                                        + messageLocator.getMessage("simplepage.not-published");
                            else
                                itemGroupString = messageLocator.getMessage("simplepage.not-published");
                        }
                        if (entityDeleted) {
                            if (itemGroupString != null)
                                itemGroupString = itemGroupString + " "
                                        + messageLocator.getMessage("simplepage.deleted-entity");
                            else
                                itemGroupString = messageLocator.getMessage("simplepage.deleted-entity");
                        }

                        if (itemGroupString != null)
                            UIOutput.make(tableRow, (isInline ? "item-group-titles-div" : "item-group-titles"),
                                    itemGroupString);
                    }

                } // end of canSeeAll

                // the following are for the inline item types. Multimedia
                // is the most complex because
                // it can be IMG, IFRAME, or OBJECT, and Youtube is treated
                // separately

            } else if (i.getType() == SimplePageItem.MULTIMEDIA) {
                // This code should be read together with the code in SimplePageBean
                // that sets up this data, method addMultimedia.  Most display is set
                // up here, but note that show-page.js invokes the jquery oembed on all
                // <A> items with class="oembed".

                // historically this code was to display files ,and urls leading to things
                // like MP4. as backup if we couldn't figure out what to do we'd put something
                // in an iframe. The one exception is youtube, which we supposed explicitly.
                //   However we now support several ways to embed content. We use the
                // multimediaDisplayType code to indicate which. The codes are
                //     1 -- embed code, 2 -- av type, 3 -- oembed, 4 -- iframe
                // 2 is the original code: MP4, image, and as a special case youtube urls
                // since we have old entries with no type code, and that behave the same as
                // 2, we start by converting 2 to null.
                //  then the logic is
                //  if type == null & youtube, do youtube
                //  if type == null & image, do iamge
                //  if type == null & not HTML do MP4 or other player for file 
                //  final fallthrough to handel the new types, with IFRAME if all else fails
                // the old code creates ojbects in ContentHosting for both files and URLs.
                // The new code saves the embed code or URL itself as an atteibute of the item
                // If I were doing it again, I wouldn't create the ContebtHosting item
                //   Note that IFRAME is only used for something where the far end claims the MIME
                // type is HTML. For weird stuff like MS Word files I use the file display code, which
                // will end up producing <OBJECT>.

                // the reason this code is complex is that we try to choose
                // the best
                // HTML for displaying the particular type of object. We've
                // added complexities
                // over time as we get more experience with different
                // object types and browsers.

                String itemGroupString = null;
                String itemGroupTitles = null;
                boolean entityDeleted = false;
                // new format explicit display indication
                String mmDisplayType = i.getAttribute("multimediaDisplayType");
                // 2 is the generic "use old display" so treat it as null
                if ("".equals(mmDisplayType) || "2".equals(mmDisplayType))
                    mmDisplayType = null;
                if (canSeeAll) {
                    try {
                        itemGroupString = simplePageBean.getItemGroupStringOrErr(i, null, true);
                    } catch (IdUnusedException e) {
                        itemGroupString = "";
                        entityDeleted = true;
                    }
                    itemGroupTitles = simplePageBean.getItemGroupTitles(itemGroupString, i);
                    if (entityDeleted) {
                        if (itemGroupTitles != null)
                            itemGroupTitles = itemGroupTitles + " "
                                    + messageLocator.getMessage("simplepage.deleted-entity");
                        else
                            itemGroupTitles = messageLocator.getMessage("simplepage.deleted-entity");
                    }
                    if (itemGroupTitles != null) {
                        itemGroupTitles = "[" + itemGroupTitles + "]";
                    }
                    UIOutput.make(tableRow, "item-groups", itemGroupString);
                } else if (entityDeleted)
                    continue;

                if (!"1".equals(mmDisplayType) && !"3".equals(mmDisplayType))
                    UIVerbatim.make(tableRow, "item-path", getItemPath(i));

                // the reason this code is complex is that we try to choose
                // the best
                // HTML for displaying the particular type of object. We've
                // added complexities
                // over time as we get more experience with different
                // object types and browsers.

                StringTokenizer token = new StringTokenizer(i.getSakaiId(), ".");

                String extension = "";

                while (token.hasMoreTokens()) {
                    extension = token.nextToken().toLowerCase();
                }

                // the extension is almost never used. Normally we have
                // the MIME type and use it. Extension is used only if
                // for some reason we don't have the MIME type
                UIComponent item;
                String youtubeKey;

                Length width = null;
                if (i.getWidth() != null) {
                    width = new Length(i.getWidth());
                }
                Length height = null;
                if (i.getHeight() != null) {
                    height = new Length(i.getHeight());
                }

                // Get the MIME type. For multimedia types is should be in
                // the html field.
                // The old code saved the URL there. So if it looks like a
                // URL ignore it.
                String mimeType = i.getHtml();
                if (mimeType != null && (mimeType.startsWith("http") || mimeType.equals(""))) {
                    mimeType = null;
                }

                // here goes. dispatch on the type and produce the right tag
                // type,
                // followed by the hidden INPUT tags with information for the
                // edit dialog
                if (mmDisplayType == null && simplePageBean.isImageType(i)) {

                    if (canSeeAll || simplePageBean.isItemAvailable(i)) {
                        UIOutput.make(tableRow, "imageSpan");

                        if (itemGroupString != null) {
                            UIOutput.make(tableRow, "item-group-titles3", itemGroupTitles);
                            UIOutput.make(tableRow, "item-groups3", itemGroupString);
                        }

                        String imageName = i.getAlt();
                        if (imageName == null || imageName.equals("")) {
                            imageName = abbrevUrl(i.getURL());
                        }

                        item = UIOutput.make(tableRow, "image")
                                .decorate(new UIFreeAttributeDecorator("src",
                                        i.getItemURL(simplePageBean.getCurrentSiteId(),
                                                currentPage.getOwner())))
                                .decorate(new UIFreeAttributeDecorator("alt", imageName));
                        if (lengthOk(width)) {
                            item.decorate(new UIFreeAttributeDecorator("width", width.getOld()));
                        }

                        if (lengthOk(height)) {
                            item.decorate(new UIFreeAttributeDecorator("height", height.getOld()));
                        }
                    } else {
                        UIComponent notAvailableText = UIOutput.make(tableRow, "notAvailableText",
                                messageLocator.getMessage("simplepage.multimediaItemUnavailable"));
                        // Grey it out
                        notAvailableText.decorate(new UIFreeAttributeDecorator("class", "disabled-text-item"));
                    }

                    // stuff for the jquery dialog
                    if (canEditPage) {
                        UIOutput.make(tableRow, "imageHeight", getOrig(height));
                        UIOutput.make(tableRow, "imageWidth", getOrig(width));
                        UIOutput.make(tableRow, "mimetype2", mimeType);
                        UIOutput.make(tableRow, "current-item-id4", Long.toString(i.getId()));
                        UIOutput.make(tableRow, "item-prereq3", String.valueOf(i.isPrerequisite()));
                        UIVerbatim.make(tableRow, "item-path3", getItemPath(i));
                        UIOutput.make(tableRow, "editimage-td");
                        UILink.make(tableRow, "image-edit", (String) null, "")
                                .decorate(new UIFreeAttributeDecorator("title",
                                        messageLocator.getMessage("simplepage.edit-title.url").replace("{}",
                                                abbrevUrl(i.getURL()))));
                    }

                    UIOutput.make(tableRow, "description2", i.getDescription());

                } else if (mmDisplayType == null && (youtubeKey = simplePageBean.getYoutubeKey(i)) != null) {
                    String youtubeUrl = SimplePageBean.getYoutubeUrlFromKey(youtubeKey);

                    if (canSeeAll || simplePageBean.isItemAvailable(i)) {
                        UIOutput.make(tableRow, "youtubeSpan");

                        if (itemGroupString != null) {
                            UIOutput.make(tableRow, "item-group-titles4", itemGroupTitles);
                            UIOutput.make(tableRow, "item-groups4", itemGroupString);
                        }

                        // if width is blank or 100% scale the height
                        if (width != null && height != null && !height.number.equals("")) {
                            if (width.number.equals("") && width.unit.equals("")
                                    || width.number.equals("100") && width.unit.equals("%")) {

                                int h = Integer.parseInt(height.number);
                                if (h > 0) {
                                    width.number = Integer.toString((int) Math.round(h * 1.641025641));
                                    width.unit = height.unit;
                                }
                            }
                        }

                        // <object style="height: 390px; width: 640px"><param
                        // name="movie"
                        // value="http://www.youtube.com/v/AKIC7OQqBrA?version=3"><param
                        // name="allowFullScreen" value="true"><param
                        // name="allowScriptAccess" value="always"><embed
                        // src="http://www.youtube.com/v/AKIC7OQqBrA?version=3"
                        // type="application/x-shockwave-flash"
                        // allowfullscreen="true" allowScriptAccess="always"
                        // width="640" height="390"></object>

                        item = UIOutput.make(tableRow, "youtubeIFrame");
                        // youtube seems ok with length and width
                        if (lengthOk(height)) {
                            item.decorate(new UIFreeAttributeDecorator("height", height.getOld()));
                        }

                        if (lengthOk(width)) {
                            item.decorate(new UIFreeAttributeDecorator("width", width.getOld()));
                        }

                        item.decorate(new UIFreeAttributeDecorator("title",
                                messageLocator.getMessage("simplepage.youtube_player")));
                        item.decorate(new UIFreeAttributeDecorator("src", youtubeUrl));
                    } else {
                        UIComponent notAvailableText = UIOutput.make(tableRow, "notAvailableText",
                                messageLocator.getMessage("simplepage.multimediaItemUnavailable"));
                        // Grey it out
                        notAvailableText.decorate(new UIFreeAttributeDecorator("class", "disabled-text-item"));
                    }

                    if (canEditPage) {
                        UIOutput.make(tableRow, "youtubeId", String.valueOf(i.getId()));
                        UIOutput.make(tableRow, "currentYoutubeURL", youtubeUrl);
                        UIOutput.make(tableRow, "currentYoutubeHeight", getOrig(height));
                        UIOutput.make(tableRow, "currentYoutubeWidth", getOrig(width));
                        UIOutput.make(tableRow, "current-item-id5", Long.toString(i.getId()));
                        UIOutput.make(tableRow, "item-prereq4", String.valueOf(i.isPrerequisite()));
                        UIVerbatim.make(tableRow, "item-path4", getItemPath(i));
                        UIOutput.make(tableRow, "youtube-td");
                        UILink.make(tableRow, "youtube-edit", (String) null, "")
                                .decorate(new UIFreeAttributeDecorator("title",
                                        messageLocator.getMessage("simplepage.edit-title.youtube")));
                    }

                    UIOutput.make(tableRow, "description4", i.getDescription());

                    // as of Oct 28, 2010, we store the mime type. mimeType
                    // null is an old entry.
                    // For that use the old approach of checking the
                    // extension.
                    // Otherwise we want to use iframes for HTML and OBJECT
                    // for everything else
                    // We need the iframes because IE up through 8 doesn't
                    // reliably display
                    // HTML with OBJECT. Experiments show that everything
                    // else works with OBJECT
                    // for most browsers. Unfortunately IE, even IE 9,
                    // doesn't reliably call the
                    // right player with OBJECT. EMBED works. But it's not
                    // as nice because you can't
                    // nest error recovery code. So we use OBJECT for
                    // everything except IE, where we
                    // use EMBED. OBJECT does work with Flash.
                    // application/xhtml+xml is XHTML.

                } else if (mmDisplayType == null && ((mimeType != null && !mimeType.equals("text/html")
                        && !mimeType.equals("application/xhtml+xml")) ||
                // ((mimeType != null && (mimeType.startsWith("audio/") || mimeType.startsWith("video/"))) || 
                        (mimeType == null && !(Arrays.binarySearch(htmlTypes, extension) >= 0)))) {

                    // except where explicit display is set,
                    // this code is used for everything that isn't an image,
                    // Youtube, or HTML
                    // This could be audio, video, flash, or something random like MS word.
                    // Random stuff will turn into an object.
                    // HTML is done with an IFRAME in the next "if" case
                    // The explicit display types are handled there as well

                    // in theory the things that fall through to iframe are
                    // html and random stuff without a defined mime type
                    // random stuff with mime type is displayed with object

                    if (mimeType == null) {
                        mimeType = "";
                    }

                    String oMimeType = mimeType; // in case we change it for
                    // FLV or others

                    if (itemGroupString != null) {
                        UIOutput.make(tableRow, "item-group-titles5", itemGroupTitles);
                        UIOutput.make(tableRow, "item-groups5", itemGroupString);
                    }

                    UIOutput.make(tableRow, "movieSpan");

                    if (canSeeAll || simplePageBean.isItemAvailable(i)) {

                        UIComponent item2;

                        String movieUrl = i.getItemURL(simplePageBean.getCurrentSiteId(),
                                currentPage.getOwner());
                        // movieUrl = "https://heidelberg.rutgers.edu" + movieUrl;
                        // Safari doens't always pass cookies to plugins, so we have to pass the arg
                        // this requires session.parameter.allow=true in sakai.properties
                        // don't pass the arg unless that is set, since the whole point of defaulting
                        // off is to not expose the session id
                        String sessionParameter = getSessionParameter(movieUrl);
                        if (sessionParameter != null)
                            movieUrl = movieUrl + "?lb.session=" + sessionParameter;

                        UIComponent movieLink = UIOutput.make(tableRow, "movie-link-div");
                        if (showDownloads)
                            UILink.make(tableRow, "movie-link-link",
                                    messageLocator.getMessage("simplepage.download_file"), movieUrl);

                        //   if (allowSessionId)
                        //  movieUrl = movieUrl + "?sakai.session=" + SessionManager.getCurrentSession().getId();
                        boolean useFlvPlayer = false;

                        // isMp4 means we try the flash player (if not HTML5)
                        // we also try the flash player for FLV but for mp4 we do an
                        // additional backup if flash fails, but that doesn't make sense for FLV
                        boolean isMp4 = Arrays.binarySearch(mp4Types, mimeType) >= 0;
                        boolean isHtml5 = Arrays.binarySearch(html5Types, mimeType) >= 0;

                        // wrap whatever stuff we decide to put out in HTML5 if appropriate
                        // javascript is used to do the wrapping, because RSF can't really handle this
                        if (isHtml5) {
                            // flag for javascript
                            boolean isAudio = mimeType.startsWith("audio/");
                            UIComponent h5video = UIOutput.make(tableRow, (isAudio ? "h5audio" : "h5video"));
                            UIComponent h5source = UIOutput.make(tableRow,
                                    (isAudio ? "h5asource" : "h5source"));
                            if (lengthOk(height) && height.getOld().indexOf("%") < 0)
                                h5video.decorate(new UIFreeAttributeDecorator("height", height.getOld()));
                            if (lengthOk(width) && width.getOld().indexOf("%") < 0)
                                h5video.decorate(new UIFreeAttributeDecorator("width", width.getOld()));
                            h5source.decorate(new UIFreeAttributeDecorator("src", movieUrl))
                                    .decorate(new UIFreeAttributeDecorator("type", mimeType));
                            String caption = i.getAttribute("captionfile");
                            if (!isAudio && caption != null && caption.length() > 0) {
                                movieLink.decorate(
                                        new UIFreeAttributeDecorator("class", "has-caption allow-caption"));
                                String captionUrl = "/access/lessonbuilder/item/" + i.getId() + caption;
                                sessionParameter = getSessionParameter(captionUrl);
                                // sessionParameter should always be non-null
                                // because this overrides all other checks in /access/lessonbuilder,
                                // we haven't adjusted it to handle these files otherwise
                                if (sessionParameter != null)
                                    captionUrl = captionUrl + "?lb.session=" + sessionParameter;
                                UIOutput.make(tableRow, "h5track")
                                        .decorate(new UIFreeAttributeDecorator("src", captionUrl));
                            } else if (!isAudio) {
                                movieLink.decorate(new UIFreeAttributeDecorator("class", "allow-caption"));
                            }
                        }

                        // FLV is special. There's no player for flash video in
                        // the browser
                        // it shows with a special flash program, which I
                        // supply. For the moment MP4 is
                        // shown with the same player so it uses much of the
                        // same code
                        if (mimeType != null
                                && (mimeType.equals("video/x-flv") || mimeType.equals("video/flv") || isMp4)) {
                            mimeType = "application/x-shockwave-flash";
                            movieUrl = "/lessonbuilder-tool/templates/StrobeMediaPlayback.swf";
                            useFlvPlayer = true;
                        }
                        // for IE, if we're not supplying a player it's safest
                        // to use embed
                        // otherwise Quicktime won't work. Oddly, with IE 9 only
                        // it works if you set CLASSID to the MIME type,
                        // but that's so unexpected that I hate to rely on it.
                        // EMBED is in HTML 5, so I think we're OK
                        // using it permanently for IE.
                        // I prefer OBJECT where possible because of the nesting
                        // ability.
                        boolean useEmbed = ieVersion > 0 && !mimeType.equals("application/x-shockwave-flash");

                        if (useEmbed) {
                            item2 = UIOutput.make(tableRow, "movieEmbed")
                                    .decorate(new UIFreeAttributeDecorator("src", movieUrl))
                                    .decorate(new UIFreeAttributeDecorator("alt",
                                            messageLocator.getMessage("simplepage.mm_player").replace("{}",
                                                    abbrevUrl(i.getURL()))));
                        } else {
                            item2 = UIOutput.make(tableRow, "movieObject")
                                    .decorate(new UIFreeAttributeDecorator("data", movieUrl))
                                    .decorate(new UIFreeAttributeDecorator("title",
                                            messageLocator.getMessage("simplepage.mm_player").replace("{}",
                                                    abbrevUrl(i.getURL()))));
                        }
                        if (mimeType != null) {
                            item2.decorate(new UIFreeAttributeDecorator("type", mimeType));
                        }
                        if (canEditPage) {
                            //item2.decorate(new UIFreeAttributeDecorator("style", "border: 1px solid black"));
                        }

                        // some object types seem to need a specification, so supply our default if necessary
                        if (lengthOk(height) && lengthOk(width)) {
                            item2.decorate(new UIFreeAttributeDecorator("height", height.getOld()))
                                    .decorate(new UIFreeAttributeDecorator("width", width.getOld()));
                        } else {
                            if (oMimeType.startsWith("audio/"))
                                item2.decorate(new UIFreeAttributeDecorator("height", "100"))
                                        .decorate(new UIFreeAttributeDecorator("width", "400"));
                            else
                                item2.decorate(new UIFreeAttributeDecorator("height", "300"))
                                        .decorate(new UIFreeAttributeDecorator("width", "400"));
                        }
                        if (!useEmbed) {
                            if (useFlvPlayer) {
                                UIOutput.make(tableRow, "flashvars")
                                        .decorate(
                                                new UIFreeAttributeDecorator("value",
                                                        "src=" + URLEncoder.encode(myUrl() + i.getItemURL(
                                                                simplePageBean.getCurrentSiteId(),
                                                                currentPage.getOwner()))));
                                // need wmode=opaque for player to stack properly with dialogs, etc.
                                // there is a performance impact, but I'm guessing in our application we don't 
                                // need ultimate performance for embedded video. I'm setting it only for
                                // the player, so flash games and other applications will still get wmode=window
                                UIOutput.make(tableRow, "wmode");
                            } else if (mimeType.equals("application/x-shockwave-flash"))
                                UIOutput.make(tableRow, "wmode");

                            UIOutput.make(tableRow, "movieURLInject")
                                    .decorate(new UIFreeAttributeDecorator("value", movieUrl));
                            if (!isMp4 && showDownloads) {
                                UIOutput.make(tableRow, "noplugin-p",
                                        messageLocator.getMessage("simplepage.noplugin"));
                                UIOutput.make(tableRow, "noplugin-br");
                                UILink.make(tableRow, "noplugin", i.getName(), movieUrl);
                            }
                        }

                        if (isMp4) {
                            // do fallback. for ie use EMBED
                            if (ieVersion > 0) {
                                item2 = UIOutput.make(tableRow, "mp4-embed")
                                        .decorate(new UIFreeAttributeDecorator("src",
                                                i.getItemURL(simplePageBean.getCurrentSiteId(),
                                                        currentPage.getOwner())))
                                        .decorate(new UIFreeAttributeDecorator("alt",
                                                messageLocator.getMessage("simplepage.mm_player").replace("{}",
                                                        abbrevUrl(i.getURL()))));
                            } else {
                                item2 = UIOutput.make(tableRow, "mp4-object")
                                        .decorate(new UIFreeAttributeDecorator("data",
                                                i.getItemURL(simplePageBean.getCurrentSiteId(),
                                                        currentPage.getOwner())))
                                        .decorate(new UIFreeAttributeDecorator("title",
                                                messageLocator.getMessage("simplepage.mm_player").replace("{}",
                                                        abbrevUrl(i.getURL()))));
                            }
                            if (oMimeType != null) {
                                item2.decorate(new UIFreeAttributeDecorator("type", oMimeType));
                            }

                            // some object types seem to need a specification, so give a default if needed
                            if (lengthOk(height) && lengthOk(width)) {
                                item2.decorate(new UIFreeAttributeDecorator("height", height.getOld()))
                                        .decorate(new UIFreeAttributeDecorator("width", width.getOld()));
                            } else {
                                if (oMimeType.startsWith("audio/"))
                                    item2.decorate(new UIFreeAttributeDecorator("height", "100"))
                                            .decorate(new UIFreeAttributeDecorator("width", "100%"));
                                else
                                    item2.decorate(new UIFreeAttributeDecorator("height", "300"))
                                            .decorate(new UIFreeAttributeDecorator("width", "100%"));
                            }

                            if (!useEmbed) {
                                UIOutput.make(tableRow, "mp4-inject")
                                        .decorate(new UIFreeAttributeDecorator("value", i.getItemURL(
                                                simplePageBean.getCurrentSiteId(), currentPage.getOwner())));

                                if (showDownloads) {
                                    UIOutput.make(tableRow, "mp4-noplugin-p",
                                            messageLocator.getMessage("simplepage.noplugin"));
                                    UILink.make(tableRow, "mp4-noplugin", i.getName(), i.getItemURL(
                                            simplePageBean.getCurrentSiteId(), currentPage.getOwner()));
                                }
                            }
                        }
                        UIOutput.make(tableRow, "description3", i.getDescription());
                    } else {
                        UIVerbatim notAvailableText = UIVerbatim.make(tableRow, "notAvailableText",
                                messageLocator.getMessage("simplepage.multimediaItemUnavailable"));
                        // Grey it out
                        notAvailableText
                                .decorate(new UIFreeAttributeDecorator("class", "disabled-multimedia-item"));
                    }

                    if (canEditPage) {
                        UIOutput.make(tableRow, "movieId", String.valueOf(i.getId()));
                        UIOutput.make(tableRow, "movieHeight", getOrig(height));
                        UIOutput.make(tableRow, "movieWidth", getOrig(width));
                        UIOutput.make(tableRow, "mimetype5", oMimeType);
                        UIOutput.make(tableRow, "prerequisite", (i.isPrerequisite()) ? "true" : "false");
                        UIOutput.make(tableRow, "current-item-id6", Long.toString(i.getId()));
                        UIVerbatim.make(tableRow, "item-path5", getItemPath(i));
                        UIOutput.make(tableRow, "movie-td");
                        UILink.make(tableRow, "edit-movie", (String) null, "")
                                .decorate(new UIFreeAttributeDecorator("title",
                                        messageLocator.getMessage("simplepage.edit-title.url").replace("{}",
                                                abbrevUrl(i.getURL()))));
                    }

                } else {
                    // this is fallthrough for html or an explicit mm display type (i.e. embed code)
                    // odd types such as MS word will be handled by the AV code, and presented as <OBJECT>

                    if (canSeeAll || simplePageBean.isItemAvailable(i)) {

                        // definition of resizeiframe, at top of page
                        if (!iframeJavascriptDone && getOrig(height).equals("auto")) {
                            UIOutput.make(tofill, "iframeJavascript");
                            iframeJavascriptDone = true;
                        }

                        UIOutput.make(tableRow, "iframeSpan");

                        if (itemGroupString != null) {
                            UIOutput.make(tableRow, "item-group-titles2", itemGroupTitles);
                            UIOutput.make(tableRow, "item-groups2", itemGroupString);
                        }
                        String itemUrl = i.getItemURL(simplePageBean.getCurrentSiteId(),
                                currentPage.getOwner());
                        if ("1".equals(mmDisplayType)) {
                            // embed
                            item = UIVerbatim.make(tableRow, "mm-embed", i.getAttribute("multimediaEmbedCode"));
                            //String style = getStyle(width, height);
                            //if (style != null)
                            //item.decorate(new UIFreeAttributeDecorator("style", style));
                        } else if ("3".equals(mmDisplayType)) {
                            item = UILink.make(tableRow, "mm-oembed", i.getAttribute("multimediaUrl"),
                                    i.getAttribute("multimediaUrl"));
                            if (lengthOk(width))
                                item.decorate(new UIFreeAttributeDecorator("maxWidth", width.getOld()));
                            if (lengthOk(height))
                                item.decorate(new UIFreeAttributeDecorator("maxHeight", height.getOld()));
                            // oembed
                        } else {
                            UIOutput.make(tableRow, "iframe-link-div");
                            UILink.make(tableRow, "iframe-link-link",
                                    messageLocator.getMessage("simplepage.open_new_window"), itemUrl);
                            item = UIOutput.make(tableRow, "iframe")
                                    .decorate(new UIFreeAttributeDecorator("src", itemUrl));
                            // if user specifies auto, use Javascript to resize the
                            // iframe when the
                            // content changes. This only works for URLs with the
                            // same origin, i.e.
                            // URLs in this sakai system
                            if (getOrig(height).equals("auto")) {
                                item.decorate(new UIFreeAttributeDecorator("onload",
                                        "resizeiframe('" + item.getFullID() + "')"));
                                if (lengthOk(width)) {
                                    item.decorate(new UIFreeAttributeDecorator("width", width.getOld()));
                                }
                                item.decorate(new UIFreeAttributeDecorator("height", "300"));
                            } else {
                                // we seem OK without a spec
                                if (lengthOk(height) && lengthOk(width)) {
                                    item.decorate(new UIFreeAttributeDecorator("height", height.getOld()))
                                            .decorate(new UIFreeAttributeDecorator("width", width.getOld()));
                                }
                            }
                        }
                        item.decorate(new UIFreeAttributeDecorator("title", messageLocator
                                .getMessage("simplepage.web_content").replace("{}", abbrevUrl(i.getURL()))));

                        if (canEditPage) {
                            UIOutput.make(tableRow, "iframeHeight", getOrig(height));
                            UIOutput.make(tableRow, "iframeWidth", getOrig(width));
                            UIOutput.make(tableRow, "mimetype3", mimeType);
                            UIOutput.make(tableRow, "item-prereq2", String.valueOf(i.isPrerequisite()));
                            UIOutput.make(tableRow, "embedtype", mmDisplayType);
                            UIOutput.make(tableRow, "current-item-id3", Long.toString(i.getId()));
                            UIVerbatim.make(tableRow, "item-path2", getItemPath(i));
                            UIOutput.make(tableRow, "editmm-td");
                            UILink.make(tableRow, "iframe-edit", (String) null, "")
                                    .decorate(new UIFreeAttributeDecorator("title",
                                            messageLocator.getMessage("simplepage.edit-title.url").replace("{}",
                                                    abbrevUrl(i.getURL()))));
                        }

                        UIOutput.make(tableRow, "description5", i.getDescription());
                    } else {

                        UIVerbatim notAvailableText = UIVerbatim.make(tableRow, "notAvailableText",
                                messageLocator.getMessage("simplepage.multimediaItemUnavailable"));
                        // Grey it out
                        notAvailableText
                                .decorate(new UIFreeAttributeDecorator("class", "disabled-multimedia-item"));
                    }

                }

                // end of multimedia object

            } else if (i.getType() == SimplePageItem.COMMENTS) {
                // Load later using AJAX and CommentsProducer

                UIOutput.make(tableRow, "commentsSpan");

                boolean isAvailable = simplePageBean.isItemAvailable(i);
                // faculty missing preqs get warning but still see the comments
                if (!isAvailable && canSeeAll)
                    UIOutput.make(tableRow, "missing-prereqs",
                            messageLocator.getMessage("simplepage.fake-missing-prereqs"));

                // students get warning and not the content
                if (!isAvailable && !canSeeAll) {
                    UIOutput.make(tableRow, "missing-prereqs",
                            messageLocator.getMessage("simplepage.missing-prereqs"));
                } else {
                    UIOutput.make(tableRow, "commentsDiv");
                    UIOutput.make(tableRow, "placementId", placement.getId());

                    // note: the URL will be rewritten in comments.js to look like
                    //  /lessonbuilder-tool/faces/Comments...
                    CommentsViewParameters eParams = new CommentsViewParameters(CommentsProducer.VIEW_ID);
                    eParams.itemId = i.getId();
                    eParams.placementId = placement.getId();
                    if (params.postedComment) {
                        eParams.postedComment = postedCommentId;
                    }
                    eParams.siteId = simplePageBean.getCurrentSiteId();
                    eParams.pageId = currentPage.getPageId();

                    if (params.author != null && !params.author.equals("")) {
                        eParams.author = params.author;
                        eParams.showAllComments = true;
                    }

                    UIInternalLink.make(tableRow, "commentsLink", eParams);

                    if (!addedCommentsScript) {
                        UIOutput.make(tofill, "comments-script");
                        UIOutput.make(tofill, "fckScript");
                        addedCommentsScript = true;
                        UIOutput.make(tofill, "delete-dialog");
                    }

                    // forced comments have to be edited on the main page
                    if (canEditPage) {
                        // Checks to make sure that the comments item isn't on a student page.
                        // That it is graded.  And that we didn't just come from the grading pane.
                        if (i.getPageId() > 0 && i.getGradebookId() != null && !cameFromGradingPane) {
                            CommentsGradingPaneViewParameters gp = new CommentsGradingPaneViewParameters(
                                    CommentGradingPaneProducer.VIEW_ID);
                            gp.placementId = toolManager.getCurrentPlacement().getId();
                            gp.commentsItemId = i.getId();
                            gp.pageId = currentPage.getPageId();
                            gp.pageItemId = pageItem.getId();
                            gp.siteId = simplePageBean.getCurrentSiteId();

                            UIInternalLink.make(tableRow, "gradingPaneLink",
                                    messageLocator.getMessage("simplepage.show-grading-pane-comments"), gp)
                                    .decorate(new UIFreeAttributeDecorator("title", messageLocator
                                            .getMessage("simplepage.show-grading-pane-comments")));
                        }

                        UIOutput.make(tableRow, "comments-td");

                        if (i.getSequence() > 0) {
                            UILink.make(tableRow, "edit-comments", (String) null, "")
                                    .decorate(new UIFreeAttributeDecorator("title",
                                            messageLocator.getMessage("simplepage.edit-title.comments")));

                            UIOutput.make(tableRow, "commentsId", String.valueOf(i.getId()));
                            UIOutput.make(tableRow, "commentsAnon", String.valueOf(i.isAnonymous()));
                            UIOutput.make(tableRow, "commentsitem-required", String.valueOf(i.isRequired()));
                            UIOutput.make(tableRow, "commentsitem-prerequisite",
                                    String.valueOf(i.isPrerequisite()));
                            UIOutput.make(tableRow, "commentsGrade",
                                    String.valueOf(i.getGradebookId() != null));
                            UIOutput.make(tableRow, "commentsMaxPoints",
                                    String.valueOf(i.getGradebookPoints()));

                            String itemGroupString = simplePageBean.getItemGroupString(i, null, true);
                            if (itemGroupString != null) {
                                String itemGroupTitles = simplePageBean.getItemGroupTitles(itemGroupString, i);
                                if (itemGroupTitles != null) {
                                    itemGroupTitles = "[" + itemGroupTitles + "]";
                                }
                                UIOutput.make(tableRow, "comments-groups", itemGroupString);
                                UIOutput.make(tableRow, "item-group-titles6", itemGroupTitles);
                            }
                        }

                        // Allows AJAX posting of comment grades
                        printGradingForm(tofill);
                    }

                    UIForm form = UIForm.make(tableRow, "comment-form");
                    makeCsrf(form, "csrf2");

                    UIInput.make(form, "comment-item-id", "#{simplePageBean.itemId}",
                            String.valueOf(i.getId()));
                    UIInput.make(form, "comment-edit-id", "#{simplePageBean.editId}");

                    // usage * image is required and not done
                    if (i.isRequired() && !simplePageBean.isItemComplete(i))
                        UIOutput.make(tableRow, "comment-required-image");

                    UIOutput.make(tableRow, "add-comment-link");
                    UIOutput.make(tableRow, "add-comment-text",
                            messageLocator.getMessage("simplepage.add-comment"));
                    UIInput fckInput = UIInput.make(form, "comment-text-area-evolved:",
                            "#{simplePageBean.formattedComment}");
                    fckInput.decorate(new UIFreeAttributeDecorator("height", "175"));
                    fckInput.decorate(new UIFreeAttributeDecorator("width", "800"));
                    fckInput.decorate(new UIStyleDecorator("evolved-box"));
                    fckInput.decorate(new UIFreeAttributeDecorator("aria-label",
                            messageLocator.getMessage("simplepage.editor")));
                    fckInput.decorate(new UIFreeAttributeDecorator("role", "dialog"));

                    if (!noEditor) {
                        fckInput.decorate(new UIStyleDecorator("using-editor")); // javascript needs to know
                        ((SakaiFCKTextEvolver) richTextEvolver).evolveTextInput(fckInput, "" + commentsCount);
                    }
                    UICommand.make(form, "add-comment", "#{simplePageBean.addComment}");
                }

            } else if (i.getType() == SimplePageItem.PEEREVAL) {

                String owner = currentPage.getOwner();
                String currentUser = UserDirectoryService.getCurrentUser().getId();
                Long pageId = currentPage.getPageId();

                UIOutput.make(tableRow, "peerReviewRubricStudent");
                UIOutput.make(tableRow, "peer-review-form");

                makePeerRubric(tableRow, i, makeStudentRubric);

                boolean isOpen = false;
                boolean isPastDue = false;

                String peerEvalDateOpenStr = i.getAttribute("rubricOpenDate");
                String peerEvalDateDueStr = i.getAttribute("rubricDueDate");
                boolean peerEvalAllowSelfGrade = Boolean.parseBoolean(i.getAttribute("rubricAllowSelfGrade"));
                boolean gradingSelf = owner.equals(currentUser) && peerEvalAllowSelfGrade;

                if (peerEvalDateOpenStr != null && peerEvalDateDueStr != null) {
                    Date peerEvalNow = new Date();
                    Date peerEvalOpen = new Date(Long.valueOf(peerEvalDateOpenStr));
                    Date peerEvalDue = new Date(Long.valueOf(peerEvalDateDueStr));

                    isOpen = peerEvalNow.after(peerEvalOpen);
                    isPastDue = peerEvalNow.after(peerEvalDue);
                }

                if (isOpen) {

                    if (owner.equals(currentUser)) { //owner gets their own data
                        class PeerEvaluation {
                            String category;
                            public int grade, count;

                            public PeerEvaluation(String category, int grade) {
                                this.category = category;
                                this.grade = grade;
                                count = 1;
                            }

                            public void increment() {
                                count++;
                            }

                            public boolean equals(Object o) {
                                if (!(o instanceof PeerEvaluation))
                                    return false;
                                PeerEvaluation pe = (PeerEvaluation) o;
                                return category.equals(pe.category) && grade == pe.grade;
                            }

                            public String toString() {
                                return category + " " + grade + " [" + count + "]";
                            }
                        }

                        ArrayList<PeerEvaluation> myEvaluations = new ArrayList<PeerEvaluation>();

                        List<SimplePagePeerEvalResult> evaluations = simplePageToolDao
                                .findPeerEvalResultByOwner(pageId.longValue(), owner);
                        if (evaluations != null)
                            for (SimplePagePeerEvalResult eval : evaluations) {
                                PeerEvaluation target = new PeerEvaluation(eval.getRowText(),
                                        eval.getColumnValue());
                                int targetIndex = myEvaluations.indexOf(target);
                                if (targetIndex != -1) {
                                    myEvaluations.get(targetIndex).increment();
                                } else
                                    myEvaluations.add(target);
                            }

                        UIOutput.make(tableRow, "my-existing-peer-eval-data");
                        for (PeerEvaluation eval : myEvaluations) {
                            UIBranchContainer evalData = UIBranchContainer.make(tableRow, "my-peer-eval-data:");
                            UIOutput.make(evalData, "peer-eval-row-text", eval.category);
                            UIOutput.make(evalData, "peer-eval-grade", String.valueOf(eval.grade));
                            UIOutput.make(evalData, "peer-eval-count", String.valueOf(eval.count));
                        }
                    }

                    if (!owner.equals(currentUser) || gradingSelf) {
                        List<SimplePagePeerEvalResult> evaluations = simplePageToolDao
                                .findPeerEvalResult(pageId, currentUser, owner);
                        //existing evaluation data
                        if (evaluations != null && evaluations.size() != 0) {
                            UIOutput.make(tableRow, "existing-peer-eval-data");
                            for (SimplePagePeerEvalResult eval : evaluations) {
                                UIBranchContainer evalData = UIBranchContainer.make(tableRow,
                                        "peer-eval-data:");
                                UIOutput.make(evalData, "peer-eval-row-text", eval.getRowText());
                                UIOutput.make(evalData, "peer-eval-grade",
                                        String.valueOf(eval.getColumnValue()));
                            }
                        }

                        //form for peer evaluation results
                        UIForm form = UIForm.make(tofill, "rubricSelection");
                        makeCsrf(form, "csrf6");

                        UIInput.make(form, "rubricPeerGrade", "#{simplePageBean.rubricPeerGrade}");
                        UICommand.make(form, "update-peer-eval-grade",
                                messageLocator.getMessage("simplepage.edit"),
                                "#{simplePageBean.savePeerEvalResult}");
                    }

                    //buttons
                    UIOutput.make(tableRow, "add-peereval-link");
                    UIOutput.make(tableRow, "add-peereval-text",
                            messageLocator.getMessage("simplepage.view-peereval"));

                    if (isPastDue) {
                        UIOutput.make(tableRow, "peer-eval-grade-directions",
                                messageLocator.getMessage("simplepage.peer-eval.past-due-date"));
                    } else if (!owner.equals(currentUser) || gradingSelf) {
                        UIOutput.make(tableRow, "save-peereval-link");
                        UIOutput.make(tableRow, "save-peereval-text",
                                messageLocator.getMessage("simplepage.save"));
                        UIOutput.make(tableRow, "cancel-peereval-link");
                        UIOutput.make(tableRow, "cancel-peereval-text",
                                messageLocator.getMessage("simplepage.cancel"));

                        UIOutput.make(tableRow, "peer-eval-grade-directions",
                                messageLocator.getMessage("simplepage.peer-eval.click-on-cell"));
                    } else { //owner who cannot grade himself
                        UIOutput.make(tableRow, "peer-eval-grade-directions",
                                messageLocator.getMessage("simplepage.peer-eval.cant-eval-yourself"));
                    }

                    if (canEditPage)
                        UIOutput.make(tableRow, "peerReviewRubricStudent-edit");//lines up rubric with edit btn column for users with editing privs
                }
            } else if (i.getType() == SimplePageItem.STUDENT_CONTENT) {

                UIOutput.make(tableRow, "studentSpan");

                boolean isAvailable = simplePageBean.isItemAvailable(i);
                // faculty missing preqs get warning but still see the comments
                if (!isAvailable && canSeeAll)
                    UIOutput.make(tableRow, "student-missing-prereqs",
                            messageLocator.getMessage("simplepage.student-fake-missing-prereqs"));
                if (!isAvailable && !canSeeAll)
                    UIOutput.make(tableRow, "student-missing-prereqs",
                            messageLocator.getMessage("simplepage.student-missing-prereqs"));
                else {
                    UIOutput.make(tableRow, "studentDiv");

                    HashMap<Long, SimplePageLogEntry> cache = simplePageBean
                            .cacheStudentPageLogEntries(i.getId());
                    List<SimpleStudentPage> studentPages = simplePageToolDao.findStudentPages(i.getId());

                    boolean hasOwnPage = false;
                    String userId = UserDirectoryService.getCurrentUser().getId();

                    Collections.sort(studentPages, new Comparator<SimpleStudentPage>() {
                        public int compare(SimpleStudentPage o1, SimpleStudentPage o2) {
                            String title1 = o1.getTitle();
                            if (title1 == null)
                                title1 = "";
                            String title2 = o2.getTitle();
                            if (title2 == null)
                                title2 = "";
                            return title1.compareTo(title2);
                        }
                    });

                    UIOutput contentList = UIOutput.make(tableRow, "studentContentTable");
                    UIOutput contentTitle = UIOutput.make(tableRow, "studentContentTitle",
                            messageLocator.getMessage("simplepage.student"));
                    contentList.decorate(
                            new UIFreeAttributeDecorator("aria-labelledby", contentTitle.getFullID()));

                    // Print each row in the table
                    for (SimpleStudentPage page : studentPages) {
                        if (page.isDeleted())
                            continue;

                        SimplePageLogEntry entry = cache.get(page.getPageId());
                        UIBranchContainer row = UIBranchContainer.make(tableRow, "studentRow:");

                        // There's content they haven't seen
                        if (entry == null || entry.getLastViewed().compareTo(page.getLastUpdated()) < 0) {
                            UIOutput.make(row, "newContentImg").decorate(new UIFreeAttributeDecorator("title",
                                    messageLocator.getMessage("simplepage.new-student-content")));
                        } else
                            UIOutput.make(row, "newContentImgT");

                        // The comments tool exists, so we might have to show the icon
                        if (i.getShowComments() != null && i.getShowComments()) {

                            // New comments have been added since they last viewed the page
                            if (page.getLastCommentChange() != null && (entry == null
                                    || entry.getLastViewed().compareTo(page.getLastCommentChange()) < 0)) {
                                UIOutput.make(row, "newCommentsImg").decorate(new UIFreeAttributeDecorator(
                                        "title", messageLocator.getMessage("simplepage.new-student-comments")));
                            } else
                                UIOutput.make(row, "newCommentsImgT");
                        }

                        // Never visited page
                        if (entry == null) {
                            UIOutput.make(row, "newPageImg").decorate(new UIFreeAttributeDecorator("title",
                                    messageLocator.getMessage("simplepage.new-student-page")));
                        } else
                            UIOutput.make(row, "newPageImgT");

                        GeneralViewParameters eParams = new GeneralViewParameters(ShowPageProducer.VIEW_ID,
                                page.getPageId());
                        eParams.setItemId(i.getId());
                        eParams.setPath("push");

                        String studentTitle = page.getTitle();

                        String sownerName = null;
                        try {
                            if (!i.isAnonymous() || canEditPage) {
                                if (page.getGroup() != null)
                                    sownerName = simplePageBean.getCurrentSite().getGroup(page.getGroup())
                                            .getTitle();
                                else
                                    sownerName = UserDirectoryService.getUser(page.getOwner()).getDisplayName();
                                if (sownerName != null && sownerName.equals(studentTitle))
                                    studentTitle = "(" + sownerName + ")";
                                else
                                    studentTitle += " (" + sownerName + ")";
                            } else if (simplePageBean.isPageOwner(page)) {
                                studentTitle += " (" + messageLocator.getMessage("simplepage.comment-you")
                                        + ")";
                            }
                        } catch (UserNotDefinedException e) {
                        }

                        UIInternalLink.make(row, "studentLink", studentTitle, eParams);

                        if (simplePageBean.isPageOwner(page)) {
                            hasOwnPage = true;
                        }

                        if (i.getGradebookId() != null && simplePageBean.getEditPrivs() == 0) {
                            UIOutput.make(row, "studentGradingCell",
                                    String.valueOf((page.getPoints() != null ? page.getPoints() : "")));
                        }
                    }

                    if (!hasOwnPage && simplePageBean.myStudentPageGroupsOk(i)) {
                        UIBranchContainer row = UIBranchContainer.make(tableRow, "studentRow:");
                        UIOutput.make(row, "linkRow");
                        UIOutput.make(row, "linkCell");

                        if (i.isRequired() && !simplePageBean.isItemComplete(i))
                            UIOutput.make(row, "student-required-image");
                        GeneralViewParameters eParams = new GeneralViewParameters(ShowPageProducer.VIEW_ID);
                        eParams.addTool = GeneralViewParameters.STUDENT_PAGE;
                        eParams.studentItemId = i.getId();
                        UIInternalLink.make(row, "linkLink", messageLocator.getMessage("simplepage.add-page"),
                                eParams);
                    }

                    String itemGroupString = null;
                    // do before canEditAll because we need itemGroupString in it
                    if (canSeeAll) {
                        itemGroupString = simplePageBean.getItemGroupString(i, null, true);
                        if (itemGroupString != null) {
                            String itemGroupTitles = simplePageBean.getItemGroupTitles(itemGroupString, i);
                            if (itemGroupTitles != null) {
                                itemGroupTitles = "[" + itemGroupTitles + "]";
                            }
                            UIOutput.make(tableRow, "item-group-titles7", itemGroupTitles);
                        }
                    }

                    if (canEditPage) {
                        // Checks to make sure that the comments are graded and that we didn't
                        // just come from a grading pane (would be confusing)
                        if (i.getAltGradebook() != null && !cameFromGradingPane) {
                            CommentsGradingPaneViewParameters gp = new CommentsGradingPaneViewParameters(
                                    CommentGradingPaneProducer.VIEW_ID);
                            gp.placementId = toolManager.getCurrentPlacement().getId();
                            gp.commentsItemId = i.getId();
                            gp.pageId = currentPage.getPageId();
                            gp.pageItemId = pageItem.getId();
                            gp.studentContentItem = true;

                            UIInternalLink.make(tableRow, "studentGradingPaneLink",
                                    messageLocator.getMessage("simplepage.show-grading-pane-content"), gp)
                                    .decorate(new UIFreeAttributeDecorator("title",
                                            messageLocator.getMessage("simplepage.show-grading-pane-content")));
                        }

                        UIOutput.make(tableRow, "student-td");
                        UILink.make(tableRow, "edit-student", (String) null, "")
                                .decorate(new UIFreeAttributeDecorator("title",
                                        messageLocator.getMessage("simplepage.edit-title.student")));

                        UIOutput.make(tableRow, "studentId", String.valueOf(i.getId()));
                        UIOutput.make(tableRow, "studentAnon", String.valueOf(i.isAnonymous()));
                        UIOutput.make(tableRow, "studentComments", String.valueOf(i.getShowComments()));
                        UIOutput.make(tableRow, "forcedAnon", String.valueOf(i.getForcedCommentsAnonymous()));
                        UIOutput.make(tableRow, "studentGrade", String.valueOf(i.getGradebookId() != null));
                        UIOutput.make(tableRow, "studentMaxPoints", String.valueOf(i.getGradebookPoints()));
                        UIOutput.make(tableRow, "studentGrade2", String.valueOf(i.getAltGradebook() != null));
                        UIOutput.make(tableRow, "studentMaxPoints2", String.valueOf(i.getAltPoints()));
                        UIOutput.make(tableRow, "studentitem-required", String.valueOf(i.isRequired()));
                        UIOutput.make(tableRow, "studentitem-prerequisite", String.valueOf(i.isPrerequisite()));
                        UIOutput.make(tableRow, "peer-eval", String.valueOf(i.getShowPeerEval()));
                        makePeerRubric(tableRow, i, makeMaintainRubric);
                        makeSamplePeerEval(tableRow);

                        String peerEvalDate = i.getAttribute("rubricOpenDate");
                        String peerDueDate = i.getAttribute("rubricDueDate");

                        Calendar peerevalcal = Calendar.getInstance();

                        if (peerEvalDate != null && peerDueDate != null) {
                            DateFormat df = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.SHORT,
                                    M_locale);
                            //Open date from attribute string
                            peerevalcal.setTimeInMillis(Long.valueOf(peerEvalDate));

                            String dateStr = isoDateFormat.format(peerevalcal.getTime());

                            UIOutput.make(tableRow, "peer-eval-open-date", dateStr);

                            //Due date from attribute string
                            peerevalcal.setTimeInMillis(Long.valueOf(peerDueDate));

                            dateStr = isoDateFormat.format(peerevalcal.getTime());

                            UIOutput.make(tableRow, "peer-eval-due-date", dateStr);
                            UIOutput.make(tableRow, "peer-eval-allow-self",
                                    i.getAttribute("rubricAllowSelfGrade"));

                        } else {
                            //Default open and due date
                            Date now = new Date();
                            peerevalcal.setTime(now);

                            //Default open date: now
                            String dateStr = isoDateFormat.format(peerevalcal.getTime());

                            UIOutput.make(tableRow, "peer-eval-open-date", dateStr);

                            //Default due date: 7 days from now
                            Date later = new Date(peerevalcal.getTimeInMillis() + 604800000);
                            peerevalcal.setTime(later);

                            dateStr = isoDateFormat.format(peerevalcal.getTime());

                            //System.out.println("Setting date to " + dateStr + " and time to " + timeStr);

                            UIOutput.make(tableRow, "peer-eval-due-date", dateStr);
                            UIOutput.make(tableRow, "peer-eval-allow-self",
                                    i.getAttribute("rubricAllowSelfGrade"));
                        }

                        //Peer Eval Stats link
                        GeneralViewParameters view = new GeneralViewParameters(PeerEvalStatsProducer.VIEW_ID);
                        view.setSendingPage(currentPage.getPageId());
                        view.setItemId(i.getId());
                        if (i.getShowPeerEval()) {
                            UILink link = UIInternalLink.make(tableRow, "peer-eval-stats-link", view);
                        }

                        if (itemGroupString != null) {
                            UIOutput.make(tableRow, "student-groups", itemGroupString);
                        }
                        UIOutput.make(tableRow, "student-owner-groups",
                                simplePageBean.getItemOwnerGroupString(i));
                        UIOutput.make(tableRow, "student-group-owned", (i.isGroupOwned() ? "true" : "false"));
                    }
                }
            } else if (i.getType() == SimplePageItem.QUESTION) {
                String itemGroupString = null;
                String itemGroupTitles = null;
                if (canSeeAll) {
                    itemGroupString = simplePageBean.getItemGroupString(i, null, true);
                    if (itemGroupString != null)
                        itemGroupTitles = simplePageBean.getItemGroupTitles(itemGroupString, i);
                    if (itemGroupTitles != null) {
                        itemGroupTitles = "[" + itemGroupTitles + "]";
                    }
                    if (canEditPage)
                        UIOutput.make(tableRow, "item-groups", itemGroupString);
                    if (itemGroupTitles != null)
                        UIOutput.make(tableRow, "questionitem-group-titles", itemGroupTitles);
                }
                SimplePageQuestionResponse response = simplePageToolDao.findQuestionResponse(i.getId(),
                        simplePageBean.getCurrentUserId());

                UIOutput.make(tableRow, "questionSpan");

                boolean isAvailable = simplePageBean.isItemAvailable(i) || canSeeAll;

                UIOutput.make(tableRow, "questionDiv");

                UIOutput.make(tableRow, "questionText", i.getAttribute("questionText"));

                List<SimplePageQuestionAnswer> answers = new ArrayList<SimplePageQuestionAnswer>();
                if ("multipleChoice".equals(i.getAttribute("questionType"))) {
                    answers = simplePageToolDao.findAnswerChoices(i);
                    UIOutput.make(tableRow, "multipleChoiceDiv");
                    UIForm questionForm = UIForm.make(tableRow, "multipleChoiceForm");
                    makeCsrf(questionForm, "csrf4");

                    UIInput.make(questionForm, "multipleChoiceId", "#{simplePageBean.questionId}",
                            String.valueOf(i.getId()));

                    String[] options = new String[answers.size()];
                    String initValue = null;
                    for (int j = 0; j < answers.size(); j++) {
                        options[j] = String.valueOf(answers.get(j).getId());
                        if (response != null && answers.get(j).getId() == response.getMultipleChoiceId()) {
                            initValue = String.valueOf(answers.get(j).getId());
                        }
                    }

                    UISelect multipleChoiceSelect = UISelect.make(questionForm, "multipleChoiceSelect:",
                            options, "#{simplePageBean.questionResponse}", initValue);
                    if (!isAvailable || response != null) {
                        multipleChoiceSelect.decorate(new UIDisabledDecorator());
                    }

                    for (int j = 0; j < answers.size(); j++) {
                        UIBranchContainer answerContainer = UIBranchContainer.make(questionForm,
                                "multipleChoiceAnswer:", String.valueOf(j));
                        UISelectChoice multipleChoiceInput = UISelectChoice.make(answerContainer,
                                "multipleChoiceAnswerRadio", multipleChoiceSelect.getFullID(), j);

                        multipleChoiceInput
                                .decorate(new UIFreeAttributeDecorator("id", multipleChoiceInput.getFullID()));
                        UIOutput.make(answerContainer, "multipleChoiceAnswerText", answers.get(j).getText())
                                .decorate(new UIFreeAttributeDecorator("for", multipleChoiceInput.getFullID()));

                        if (!isAvailable || response != null) {
                            multipleChoiceInput.decorate(new UIDisabledDecorator());
                        }
                    }

                    UICommand answerButton = UICommand.make(questionForm, "answerMultipleChoice",
                            messageLocator.getMessage("simplepage.answer_question"),
                            "#{simplePageBean.answerMultipleChoiceQuestion}");
                    if (!isAvailable || response != null) {
                        answerButton.decorate(new UIDisabledDecorator());
                    }
                } else if ("shortanswer".equals(i.getAttribute("questionType"))) {
                    UIOutput.make(tableRow, "shortanswerDiv");

                    UIForm questionForm = UIForm.make(tableRow, "shortanswerForm");
                    makeCsrf(questionForm, "csrf5");

                    UIInput.make(questionForm, "shortanswerId", "#{simplePageBean.questionId}",
                            String.valueOf(i.getId()));

                    UIInput shortanswerInput = UIInput.make(questionForm, "shortanswerInput",
                            "#{simplePageBean.questionResponse}");
                    if (!isAvailable || response != null) {
                        shortanswerInput.decorate(new UIDisabledDecorator());
                        if (response != null && response.getShortanswer() != null) {
                            shortanswerInput.setValue(response.getShortanswer());
                        }
                    }

                    UICommand answerButton = UICommand.make(questionForm, "answerShortanswer",
                            messageLocator.getMessage("simplepage.answer_question"),
                            "#{simplePageBean.answerShortanswerQuestion}");
                    if (!isAvailable || response != null) {
                        answerButton.decorate(new UIDisabledDecorator());
                    }
                }

                Status questionStatus = getQuestionStatus(i, response);
                addStatusImage(questionStatus, tableRow, "questionStatus", null);
                String statusNote = getStatusNote(questionStatus);
                if (statusNote != null) // accessibility version of icon
                    UIOutput.make(tableRow, "questionNote", statusNote);
                String statusText = null;
                if (questionStatus == Status.COMPLETED)
                    statusText = i.getAttribute("questionCorrectText");
                else if (questionStatus == Status.FAILED)
                    statusText = i.getAttribute("questionIncorrectText");
                if (statusText != null && !"".equals(statusText.trim()))
                    UIOutput.make(tableRow, "questionStatusText", statusText);

                // Output the poll data
                if ("multipleChoice".equals(i.getAttribute("questionType"))
                        && (canEditPage || ("true".equals(i.getAttribute("questionShowPoll"))
                                && (questionStatus == Status.COMPLETED || questionStatus == Status.FAILED)))) {
                    UIOutput.make(tableRow, "showPollGraph", messageLocator.getMessage("simplepage.show-poll"));
                    UIOutput questionGraph = UIOutput.make(tableRow, "questionPollGraph");
                    questionGraph.decorate(new UIFreeAttributeDecorator("id", "poll" + i.getId()));

                    List<SimplePageQuestionResponseTotals> totals = simplePageToolDao.findQRTotals(i.getId());
                    HashMap<Long, Long> responseCounts = new HashMap<Long, Long>();
                    // in theory we don't need the first loop, as there should be a total
                    // entry for all possible answers. But in case things are out of sync ...
                    for (SimplePageQuestionAnswer answer : answers)
                        responseCounts.put(answer.getId(), 0L);
                    for (SimplePageQuestionResponseTotals total : totals)
                        responseCounts.put(total.getResponseId(), total.getCount());

                    for (int j = 0; j < answers.size(); j++) {
                        UIBranchContainer pollContainer = UIBranchContainer.make(tableRow, "questionPollData:",
                                String.valueOf(j));
                        UIOutput.make(pollContainer, "questionPollText", answers.get(j).getText());
                        UIOutput.make(pollContainer, "questionPollNumber",
                                String.valueOf(responseCounts.get(answers.get(j).getId())));
                    }
                }

                if (canEditPage) {
                    UIOutput.make(tableRow, "question-td");

                    // always show grading panel. Currently this is the only way to get feedback
                    if (!cameFromGradingPane) {
                        QuestionGradingPaneViewParameters gp = new QuestionGradingPaneViewParameters(
                                QuestionGradingPaneProducer.VIEW_ID);
                        gp.placementId = toolManager.getCurrentPlacement().getId();
                        gp.questionItemId = i.getId();
                        gp.pageId = currentPage.getPageId();
                        gp.pageItemId = pageItem.getId();

                        UIInternalLink
                                .make(tableRow, "questionGradingPaneLink",
                                        messageLocator.getMessage("simplepage.show-grading-pane"), gp)
                                .decorate(new UIFreeAttributeDecorator("title",
                                        messageLocator.getMessage("simplepage.show-grading-pane")));
                    }

                    UILink.make(tableRow, "edit-question", (String) null, "")
                            .decorate(new UIFreeAttributeDecorator("title",
                                    messageLocator.getMessage("simplepage.edit-title.question")));

                    UIOutput.make(tableRow, "questionId", String.valueOf(i.getId()));
                    boolean graded = "true".equals(i.getAttribute("questionGraded"))
                            || i.getGradebookId() != null;
                    UIOutput.make(tableRow, "questionGrade", String.valueOf(graded));
                    UIOutput.make(tableRow, "questionMaxPoints", String.valueOf(i.getGradebookPoints()));
                    UIOutput.make(tableRow, "questionGradebookTitle", String.valueOf(i.getGradebookTitle()));
                    UIOutput.make(tableRow, "questionitem-required", String.valueOf(i.isRequired()));
                    UIOutput.make(tableRow, "questionitem-prerequisite", String.valueOf(i.isPrerequisite()));
                    UIOutput.make(tableRow, "questionitem-groups", itemGroupString);
                    UIOutput.make(tableRow, "questionCorrectText",
                            String.valueOf(i.getAttribute("questionCorrectText")));
                    UIOutput.make(tableRow, "questionIncorrectText",
                            String.valueOf(i.getAttribute("questionIncorrectText")));

                    if ("shortanswer".equals(i.getAttribute("questionType"))) {
                        UIOutput.make(tableRow, "questionType", "shortanswer");
                        UIOutput.make(tableRow, "questionAnswer", i.getAttribute("questionAnswer"));
                    } else {
                        UIOutput.make(tableRow, "questionType", "multipleChoice");

                        for (int j = 0; j < answers.size(); j++) {
                            UIBranchContainer answerContainer = UIBranchContainer.make(tableRow,
                                    "questionMultipleChoiceAnswer:", String.valueOf(j));
                            UIOutput.make(answerContainer, "questionMultipleChoiceAnswerId",
                                    String.valueOf(answers.get(j).getId()));
                            UIOutput.make(answerContainer, "questionMultipleChoiceAnswerText",
                                    answers.get(j).getText());
                            UIOutput.make(answerContainer, "questionMultipleChoiceAnswerCorrect",
                                    String.valueOf(answers.get(j).isCorrect()));
                        }

                        UIOutput.make(tableRow, "questionShowPoll",
                                String.valueOf(i.getAttribute("questionShowPoll")));
                    }
                }
            } else {
                // remaining type must be a block of HTML
                UIOutput.make(tableRow, "itemSpan");

                if (canSeeAll) {
                    String itemGroupString = simplePageBean.getItemGroupString(i, null, true);
                    String itemGroupTitles = simplePageBean.getItemGroupTitles(itemGroupString, i);
                    if (itemGroupTitles != null) {
                        itemGroupTitles = "[" + itemGroupTitles + "]";
                    }

                    UIOutput.make(tableRow, "item-groups-titles-text", itemGroupTitles);
                }

                if (canSeeAll || simplePageBean.isItemAvailable(i)) {
                    UIVerbatim.make(tableRow, "content", (i.getHtml() == null ? "" : i.getHtml()));
                } else {
                    UIComponent unavailableText = UIOutput.make(tableRow, "content",
                            messageLocator.getMessage("simplepage.textItemUnavailable"));
                    unavailableText.decorate(new UIFreeAttributeDecorator("class", "disabled-text-item"));
                }

                // editing is done using a special producer that calls FCK.
                if (canEditPage) {
                    GeneralViewParameters eParams = new GeneralViewParameters();
                    eParams.setSendingPage(currentPage.getPageId());
                    eParams.setItemId(i.getId());
                    eParams.viewID = EditPageProducer.VIEW_ID;
                    UIOutput.make(tableRow, "edittext-td");
                    UIInternalLink.make(tableRow, "edit-link", (String) null, eParams)
                            .decorate(new UIFreeAttributeDecorator("title",
                                    messageLocator.getMessage("simplepage.edit-title.textbox").replace("{}",
                                            Integer.toString(textboxcount))));
                    textboxcount++;
                }
            }
        }

        // end of items. This is the end for normal users. Following is
        // special
        // checks and putting out the dialogs for the popups, for
        // instructors.

        boolean showBreak = false;

        // I believe refresh is now done automatically in all cases
        // if (showRefresh) {
        // UIOutput.make(tofill, "refreshAlert");
        //
        // // Should simply refresh
        // GeneralViewParameters p = new GeneralViewParameters(VIEW_ID);
        // p.setSendingPage(currentPage.getPageId());
        // UIInternalLink.make(tofill, "refreshLink", p);
        // showBreak = true;
        // }

        // stuff goes on the page in the order in the HTML file. So the fact
        // that it's here doesn't mean it shows
        // up at the end. This code produces errors and other odd stuff.

        if (canSeeAll) {
            // if the page is hidden, warn the faculty [students get stopped
            // at
            // the top]
            if (currentPage.isHidden()) {
                UIOutput.make(tofill, "hiddenAlert").decorate(new UIFreeAttributeDecorator("title",
                        messageLocator.getMessage("simplepage.pagehidden")));
                UIVerbatim.make(tofill, "hidden-text", messageLocator.getMessage("simplepage.pagehidden.text"));

                showBreak = true;
                // similarly warn them if it isn't released yet
            } else if (currentPage.getReleaseDate() != null && currentPage.getReleaseDate().after(new Date())) {
                DateFormat df = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.SHORT, M_locale);
                TimeZone tz = timeService.getLocalTimeZone();
                df.setTimeZone(tz);
                String releaseDate = df.format(currentPage.getReleaseDate());
                UIOutput.make(tofill, "hiddenAlert").decorate(new UIFreeAttributeDecorator("title",
                        messageLocator.getMessage("simplepage.notreleased")));
                UIVerbatim.make(tofill, "hidden-text",
                        messageLocator.getMessage("simplepage.notreleased.text").replace("{}", releaseDate));
                showBreak = true;
            }
        }

        if (showBreak) {
            UIOutput.make(tofill, "breakAfterWarnings");
        }
    }

    // more warnings: if no item on the page, give faculty instructions,
    // students an error
    if (!anyItemVisible) {
        if (canEditPage) {
            String helpUrl = null;
            // order:
            // localized placedholder
            // localized general
            // default placeholder
            // we know the defaults exist because we include them, so
            // we never need to consider default general
            if (currentPage.getOwner() != null)
                helpUrl = getLocalizedURL("student.html", true);
            else {
                helpUrl = getLocalizedURL("placeholder.html", false);
                if (helpUrl == null)
                    helpUrl = getLocalizedURL("general.html", false);
                if (helpUrl == null)
                    helpUrl = getLocalizedURL("placeholder.html", true);
            }

            UIOutput.make(tofill, "startupHelp").decorate(new UIFreeAttributeDecorator("src", helpUrl))
                    .decorate(new UIFreeAttributeDecorator("id", "iframe"));
            if (!iframeJavascriptDone) {
                UIOutput.make(tofill, "iframeJavascript");
                iframeJavascriptDone = true;
            }
        } else {
            UIOutput.make(tofill, "error-div");
            UIOutput.make(tofill, "error", messageLocator.getMessage("simplepage.noitems_error_user"));
        }
    }

    // now output the dialogs. but only for faculty (to avoid making the
    // file bigger)
    if (canEditPage) {
        createSubpageDialog(tofill, currentPage);
    }

    createDialogs(tofill, currentPage, pageItem);
}

From source file:org.sakaiproject.lessonbuildertool.tool.beans.SimplePageBean.java

public String addAssignment() {
    DateFormat df = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.SHORT,
            new ResourceLoader().getLocale());
    df.setTimeZone(TimeService.getLocalTimeZone());
    if (!itemOk(itemId))
        return "permission-failed";
    if (!canEditPage())
        return "permission-failed";
    if (!checkCsrf())
        return "permission-failed";

    if (selectedAssignment == null) {
        return "failure";
    } else {//from   w  w w  .  j av a2  s .c o  m
        try {
            LessonEntity selectedObject = assignmentEntity.getEntity(selectedAssignment);
            if (selectedObject == null)
                return "failure";

            SimplePageItem i;
            // editing existing item?
            if (itemId != null && itemId != -1) {
                i = findItem(itemId);

                // if no change, don't worry
                LessonEntity existing = assignmentEntity.getEntity(i.getSakaiId());
                String ref = null;
                if (existing != null)
                    ref = existing.getReference();
                // if same quiz, nothing to do
                if ((existing == null) || !ref.equals(selectedAssignment)) {
                    // if access controlled, clear restriction from old assignment and add to new
                    if (i.isPrerequisite()) {
                        if (existing != null) {
                            i.setPrerequisite(false);
                            checkControlGroup(i, false);
                        }
                        // sakaiid and name are used in setting control
                        i.setSakaiId(selectedAssignment);
                        i.setName(selectedObject.getTitle());
                        i.setPrerequisite(true);
                        checkControlGroup(i, true);
                    } else {
                        i.setSakaiId(selectedAssignment);
                        i.setName(selectedObject.getTitle());
                    }
                    // reset assignment-specific stuff
                    // Because we don't update the due date when it changes, this raises more
                    // problems than it fixes. It's also done only for assignments and not tests
                    //   if (selectedObject.getDueDate() != null)
                    //    i.setDescription("(" + messageLocator.getMessage("simplepage.due") + " " + df.format(selectedObject.getDueDate()) + ")");
                    //  else
                    // i.setDescription(null);

                    update(i);
                }
            } else {
                // no, add new item
                i = appendItem(selectedAssignment, selectedObject.getTitle(), SimplePageItem.ASSIGNMENT);
                //if (selectedObject.getDueDate() != null)
                //  i.setDescription("(" + messageLocator.getMessage("simplepage.due") + " " + df.format(selectedObject.getDueDate()) + ")");
                //else
                i.setDescription(null);
                update(i);
            }
            return "success";
        } catch (Exception ex) {
            ex.printStackTrace();
            return "failure";
        } finally {
            selectedAssignment = null;
        }
    }
}