diff --git a/config/alfresco/messages/webclient.properties b/config/alfresco/messages/webclient.properties index 7d6c8e76b4..8c3ed1b10f 100644 --- a/config/alfresco/messages/webclient.properties +++ b/config/alfresco/messages/webclient.properties @@ -1,1214 +1,1216 @@ -# I18N message properties - -# Date Pattern -date_pattern=d MMMM yyyy -date_time_pattern=d MMMM yyyy HH:mm -time_pattern=HH:mm - -# General UI -product_name=Alfresco -view_description=This view allows you to browse the items in this space. -search_description=This view allows you to see the results from your search. -checkinfile_description=Check in your working copy for other team members to work with. -checkoutfilelink_description=Edit the checked out file, undo the check out or carry on working. -checkoutfile_description=Enter information about the check out. -documentdetails_description=View the details about the content. -linkdetails_description=View the details about the link object. -previewdocument_description=Preview the content or space within a Template. -spacedetails_description=View the details about the space. -undocheckoutfile_description=Cancel the check out of a document and discard any changes. -updatefile_description=Update a document on the repository with content from your computer. -editfile_description=Edit the content of the file. -editfileinline_description=Edit the content of the document, then click Save. -createfile_description=Enter new content. -manageusers_description=Manage the users of the repository. -manage_invited_users_description=Manage the permissions you have granted to users who access your space. -manage_content_users_description=Manage the permissions you have granted to users who access your content. -modify_user_roles_description=Modify the permissions granted to a user for accessing your space. -modify_content_user_roles_description=Modify the permissions granted to a user for accessing your content. -advancedsearch_description=Perform a more detailed search of the repository. -edit_content_description=Modify the content properties then click OK. -view_content_description=View the content properties. -editcategory_description=Set the category for the document then click OK. -editcategory_space_description=Set the category for the space then click OK. -editworkflow_description=Modify the simple workflow properties then click OK. -editspace_description=Modify the space properties then click OK. -editlink_description=Modify the link object properties then click OK. -create_space_description=Enter information about the new space then click Create Space. -space_rules_description=This view shows you all the rules to be applied to content in this space. -warning_inline=This is only recommended for HTML or plain text documents. -categories_description=This view allows you to browse and modify the categories hiearchy. -new_category_description=Enter information about the new Category then click Create Category. -status_message_default=No messages. - -# UI Component messages -yes=Yes -no=No -kilobyte=KB -megabyte=MB -gigabyte=GB -locked_you=Item locked by you -locked_user=Item locked by user -wizard_errors=Please correct the errors below. -last_page=Last Page -next_page=Next Page -prev_page=Previous Page -first_page=First Page -page_info=Page {0} of {1} -go_up=Go Up -ok=OK -go=Go -to=To -from=From -options=Options -other_options=Other Options -local=Local -inherited=Inherited -search=Search -advanced_search=Advanced Search -value_not_set=not set -clear=Clear Results -results_contains=Results for ''{0}''. -results_contains_filter=Results for ''{0}'' in ''{1}''. -details_view=Details View -view_icon=Icon View -view_browse=Browse View -create_options=Create -more_options=More... -more_actions=More Actions -more_options_space=More Actions for this Space -more_options_file=More Actions for this Document -select_space_prompt=Click here to select a Space -select_existing_space_prompt=Click here to select an existing Space -select_home_space_prompt=Click here to select the Home Space location -select_category_prompt=Click here to select a Category -select_destination_prompt=Click here to select the destination -add_new=Add New -change=Change -set=Set -no_categories_applied=This document does not yet have any categories applied. -has_following_categories=This document has the following categories applied... -no_categories_applied_space=This space does not yet have any categories applied. -has_following_categories_space=This space has the following categories applied... -moved=moved -copied=copied -document_action=The document will be {0} to ''{1}'' if the ''{2}'' action is taken. -clipboard=Clipboard -recent_spaces=Recent Spaces -shortcuts=Shortcuts -company_home=Company Home -my_home=My Home -guest_home=Guest Home -new_search=New Search -search_results=Search Results -search_detail=Search for \"{0}\" results shown below -close_search=Close Search -browse_spaces=Browse Spaces -browse_content=Content items -location=Location -toggle_shelf=Hide or Show the Shelf -shelf=Shelf -actions=Actions -view=View -view_details=View Details -view_details_file=View Details for file -change_details=Change Details -update=Update -cut=Cut -copy=Copy -paste=Paste -remove=Remove -change_roles=Change Roles -change_user_roles=Change User Roles -paste_item=Paste Item -paste_link=Paste As Link -paste_all=Paste All -remove_item=Remove Item -remove_all=Remove All -close=Close -invite=Invite -invite_user=Invite User -filter_contents=Filter Contents -users=Users -groups=Groups -resetall=Reset All -content_rules=Content Rules -view_in_browser=View In Browser -view_in_webdav=View in WebDAV -view_in_cifs=View in CIFS -download_content=Download Content -details_page_bookmark=External Access URL -noderef_link=Alfresco Node Reference -links=Links -create_shortcut=Create Shortcut -navigation=Navigation -next_item=Next Item -previous_item=Previous Item -cancel=Cancel -upload=Upload -homespace=Home Space -network_folder=Open Network Folder -other_action=Run Action -information=Information -move=Move -type=Type -aspect=Aspect -workflow=Workflow -rules=Rules -system_error=System Error -login=Login -templates=Templates -template=Template -rss_template=RSS Template -select_button=Select... -select_items=Select items -select_an_item=Select an item -selected_items=Selected Items -add_to_list_button=Add to List -none=None -no_selected_items=No selected items. -search_select_item=Search for and select an item. -search_select_items=Search for and select items. -search_minimum=Not enough information was entered to perform a search, at least one value must be entered or a location selected to search within. Text fields require a minimum of {0} characters. -filter=Filter -choose_icon=Choose icon -security=Security -all_formats=All Formats -rules_count=Number of rules applied to this Space -working_copy_document=Working Copy -copy_of=Copy of -link_to=Link to -icon=Icon -lock=Lock -unlock=Unlock -items_per_page=Items Per Page -raise_issue=Raise an Issue -click_to_set_date=Click to set a date -today=Today -reset=Reset - -# Properties -username=User Name -joindate=Join Date -roles=Roles -help=Help -name=Name -password=Password -confirm=Confirm -path=Path -description=Description -created=Created -modified=Modified -created_date=Created Date -modified_date=Modified Date -size=Size -title=Title -author=Author -date=Date -mimetype=Format - -# Repo permission display labels -# Note - these come from the server, the english translation is generally the same -Administrator=Administrator -Consumer=Consumer -Read=Consumer -Coordinator=Coordinator -Collaborator=Collaborator -Contributor=Contributor -Editor=Editor -All=All - -# Actions -delete=Delete -edit=Edit -checkin=Check In -checkout=Check Out -checkout_document=Check out this document -undocheckout=Undo Check Out -delete_space=Delete Space -delete_file=Delete File -delete_rule=Delete Rule -delete_user=Delete User -remove_user=Remove User -create_space=Create Space -add_content=Add Content -create_content=Create Content -create_xml_content_type=Create XML Content Type -add_multiple_files=Add Multiple Files -import_directory=Import Directory -advanced_space_wizard=Advanced Space Wizard -create_rule=Create Rule -reapply_rules=Reapply Rules -reapply_rules_success=The rules have been successfully reapplied. -ignore_inherited_rules=Ignore Inherited Rules -include_inherited_rules=Include Inherited Rules -inherited_rules_being_ignored=Inherited rules are being ignored. -manage_rules=Manage Content Rules -manage_users=Manage System Users -manage_groups=Manage User Groups -manage_invited_users=Manage Space Users -manage_content_users=Manage Content Users -modify_user_roles=Modify User Roles for -modify=Modify -logout=Logout -add=Add -node_browser=Node Browser -reset_config=Reset Config Service -save=Save -user_details=User Details -language=Language -export=Export -import=Import -take_ownership=Take Ownership -create_forums=Create Forum Space -create_forum=Create Forum -create_topic=Create Topic -create_post=Create Post -create_reply=Post Reply -delete_forums=Delete Forum Space -delete_forum=Delete Forum -delete_topic=Delete Topic -delete_post=Delete Post -post_to_topic=Post to Topic -reply=Reply -edit_post=Edit Post -reply_to=Reply to -post_reply=Post Reply - -# Login page message -login_details=Enter Login details -login_err_password_length=Password must be between {0} and {1} characters in length. -login_err_password_chars=Password can only contain characters or digits. -login_err_username_length=Username must be between {0} and {1} characters in length. -login_err_username_chars=Username can only contain characters or digits. -loggedout_details=You have been logged out of Alfresco. -relogin=Re-login to Alfresco -no_access=You have no access to Alfresco. -no_cookies=Cookies must be enabled in your browser for the Alfresco Web-Client to function correctly. -user_err_user_name=User ID cannot contain the characters: {0} - -# Browse list messages -no_space_items=No items to display. Click the ''{0}'' action to create a space. -no_content_items=No items to display. To add an existing document click ''{0}'' action. To create an HTML or Plain Text file click ''{1}'' action. - -# Advanced Search messages -look_in=Look in location -look_for=Look for -all_spaces=All Spaces -specify_space=Specify Space -include_child_spaces=Include child spaces -show_results_for=Show me results for -all_items=All Items -file_names_contents=File names and contents -file_names=File names only -space_names=Space names only -show_results_categories=Show me results in the categories -include_sub_categories=Include sub-categories -also_search_results=More search options -additional_options=Additional options -save_new_search=Save New Search -save_edit_search=Save Modified Search -saved_searches=My Saved Search Options -title_save_search=Save Search Query -save_search_description=Save a search query for use again later -search_props=Saved Search Properties -select_saved_search=Select a Saved Search... -saved_search_warning=This operation will attempt to overwrite the existing saved search ''{0}'' -user_searches=Your Searches -global_searches=Public Searches -save_search_global=Save as a public search available to all users. -folder_type=Folder Type - -# Forum messages -forums=Forum Space -forum=Forum -browse_forums=Browse Forum Spaces and Forums -browse_topics=Browse Topics -browse_posts=Browse Posts -forums_info=This view allows you to browse forum spaces and forums. -forum_info=This view allows you to browse topics in this forum. -topic_info=This view allows you to browse posts in this topic. -no_forums=No forum spaces or forums to display. Click the ''Create Forum Space'' action to create a forum space or ''Create Forum'' action to create a forum. -no_topics=No topics to display. Click the ''Create Topic'' action to create a topic. -no_posts=No posts to display. Click the ''Post to Topic'' action to create a post. -topic=Topic -topics=Topics -post=Post -posted=Posted -create_forums_description=Enter information about the new forum space then click Create Forum Space. -create_forum_description=Enter information about the new forum then click Create Forum. -create_topic_description=Enter information about the new topic then click Create Topic. -create_post_description=Enter the content of the message then click Post. -create_reply_description=Enter message text to reply then click Reply. -modify_forums_properties=Modify Forum Space Properties -forums_props=Forum Space Properties -modify_forum_properties=Modify Forum Properties -forum_props=Forum Properties -topic_props=Topic Properties -modify_topic_properties=Modify Topic Properties -create_forums_finish=To create the forum space click Create Forum Space. -create_forum_finish=To create the forum click Create Forum. -create_topic_finish=To create the topic click Create Topic. -create_post_finish=To create the post click Post. -create_reply_finish=To create the reply click Reply. -forums_details_description=View details about the forum space. -forum_details_description=View details about the forum. -topic_details_description=View details about the topic. -bubble_view=Bubble View -replies=Replies -on=On -reply_message=Reply Message -edit_forums_description=Modify the forum space properties then click OK. -edit_forum_description=Modify the forum properties then click OK. -edit_topic_description=Modify the topic properties then click OK. -edit_post_description=Modify the message then click OK. -edit_post_finish=To save the message click Post. -start_discussion=Start Discussion -discuss=View Discussions -discussion_for={0} discussion - -# Common Wizard messages -steps=Steps -summary=Summary -summary_desc=The information you entered is shown below. -default_instruction=To continue click Next. -next_button=Next -back_button=Back -finish_button=Finish -cancel_button=Cancel -clear_button=Clear -you_may_want=You may want to -summary_step_description=Shows a summary of the information entered. - -# Category Management messages -title_categories_list=Categories -add_category=Add Category -edit_category=Edit Category -delete_category=Delete Category -category_icons=Categories -category_details=Details -category_management=Category Management -title_create_category=Create New Category -new_category=New Category -category_props=Category Properties -items=Items -title_delete_category=Delete Category -delete_category_warning=This category has {0} existing document(s) linked to it. -delete_category_info=To remove this category and all it's sub-categories, click Delete. -delete_category_confirm=Are you sure you want to delete category \"{0}\" and all sub-categories? -title_edit_category=Edit Category -edit_category_description=Edit the information for this category. - -# Groups Management messages -title_groups_list=Groups Management -groups_management=Groups Management -groups_description=Manage the members of a group, create new groups or remove existing groups. -new_group=Create Group -new_sub_group=Create Sub-Group -edit_group=Edit Group -delete_group=Delete Group -add_user=Add User -group_icons=Groups -group_details=Details -root_groups=Root Groups -group_filter_children=Children -group_filter_all=All -title_create_group=Create Group -new_group_description=Enter information about the new Group then click Create Group. -group_props=Group Properties -identifier=Identifier -create_group_warning=The Identifier for a Group cannot be changed once it has been set. -title_delete_group=Delete Group -delete_group_warning=This group has {0} sub-group(s) or user(s) attached to it. -delete_group_info=To delete this Group from the system and remove all members from it, click Delete. -delete_group_confirm=Once the group is removed from the system it will no longer be accessable. Are you sure you want to delete Group \"{0}\" and remove all users from it? -title_add_user_group=Add User to Group -add_user_group_description=Add an existing User to a Group -select_users=Select Users to add to this Group -selected_users=Selected Users -groups_err_group_name=Group ID cannot contain the characters: {0} -groups_err_exists=A group ID with the same name already exists, group identifiers must be unique. - -# Invite Users Wizard messages -invite_title=Invite Users Wizard -invite_desc=This wizard helps you to give other users access to your space. -invite_step1_title=Step One - Invite Users -invite_step1_desc=Select the users and roles they will play in this space. -invite_step2_title=Step Two - Notify Users -invite_step2_desc=Notify the selected users. -i_want_to=I want to... -invite_step_1=Invite Users -invite_step_2=Notify Users -invite_all=Invite All users as guests -invite_users=Specify Users/Groups and their roles -specify_usersgroups=Specify Users/Groups -select_usersgroups=Select user/group and their role(s) -select_role=Select role -selected_usersgroups=Selected users/groups and their role(s) -selected_roles=Selected roles -click_add=Click Add -role=Role -send_email=Do you want to send an email to notify the invited users? -subject=Subject -body=Body -automatic_text=Automatic text -invited_to=You have been invited to ''{0}'' by {1}. -invite_role=You will have the role of: {0} -invite_finish_instruction=To close this wizard and apply your changes click Finish. To review or change your selections click Back. -remove_invited_user_info=To remove an invited user from this space, click Yes. -add_role=Add Role -space_owner=User ''{0}'' is the current owner of this space. -users_and_groups=Users and Groups -authority=Username - -# Invite Content Users Wizard messages -invite_content_title=Invite Content Users Wizard -invite_content_desc=This wizard helps you to give other users access to your content. -invite_content_step1_desc=Select the users and roles they will play for this content. -remove_content_user_info=To remove an invited user from this content, click Yes. -content_owner=User ''{0}'' is the current owner of this content. - -# System Users messages -create_user=Create User -change_password=Change Password -title_change_password=Change User Password -change_password_description=Use this view to change an existing user password. -change_password_instructions=Enter the new password for this user. -show_all=Show All - -# Check-in messages -check_in=Check In -checkin_options=Check In options -checkin_changes_info=Check in changes and keep file checked out -workingcopy_location=Working copy location -which_copy_checkin=Which copy do you want to check in? -which_copy_current=Use copy in current space -which_copy_other=Use copy uploaded from my computer -locate_doc_upload=Locate document to upload -file_location=Location -minor_change=Minor Change -major_change=Major Change -notes=Notes - -# Check-out messages -check_out=Check Out -copy_work_with=A copy of the file ''{0}'' will be made for you to work with. -copy_checkin_changes=When you have completed your changes you need to check in the file to allow others to view the changes. -copy_store_prompt=Where do you want to keep the copy of this file? -store_space_current=In the current space -store_space_selected=In the space selected -check_out_of=Check Out of -copy_file_checkedout=A copy of the file ''{0}'' is now checked out to you for editing. -edit_workingcopy_title=Edit the working copy now -edit_workingcopy_info=To edit the working copy of the file, click the link below and if asked select Save. -continue_working_title=Continue working -continue_working_info1=If you do not want to edit the file now click OK to close the page. -continue_working_info2=To edit the file in the future click the Edit action -download_complete=When the download is complete, click OK. -undo_checkout_for=Undo Check Out for -undo_checkout=Undo Check Out -undo_checkout_info=If you undo the check out of a document, the associated working copy will be deleted and all changes to it since the Check Out will be lost. - -# Document and Space details messages -details_of=Details of -preview_of=Preview of -modify_props_of=Modify Properties of -modify_space_properties=Modify Space Properties -modify_content_properties=Modify Content Properties -view_content_properties=View Content Properties -preview=Preview in Template -custom_view=Custom View -view_links=Links -not_inline_editable=This document is not inline editable. -allow_inline_editing=Allow Inline Editing -not_in_workflow=This document is not part of any workflow. -not_in_category=This document is not categorized. -not_in_category_space=This space is not categorized. -not_versioned=This document has no version history. -allow_categorization=Allow Categorization -allow_versioning=Allow Versioning -version_history=Version History -version=Version -document_properties=Document Properties -link_properties=Link Properties -general_properties=General Properties -other_properties=Other Properties -link_destination=Link Destination -link_destination_details=Link Destination Details -no_other_properties=This document does not have any other properties to show. -modify_categories_of=Modify categories of -space_props=Space Properties -choose_space_icon=Choose space icon -create_space_finish=To create your space click Create Space. -select_category=Select a category -selected_categories=Selected categories -no_selected_categories=No categories selected. -success_ownership=Successfully took ownership of the object. -success_unlock=Successfully unlocked the document. -inherit_permissions=Inherit Parent Space Permissions -success_inherit_permissions=Successfully changed Inherit Parent Permissions to 'Yes' -success_not_inherit_permissions=Successfully changed Inherit Parent Permissions to 'No' -apply_template=Apply Template -apply_dashboard_info=Select a template to be applied to the Space as a Custom view. -apply_dashboard_doc_info=Select a template to be applied to the Document as a Custom view. -apply_rss_feed=Apply RSS Feed Template -apply_rss_feed_info=Select a template to be applied to the Space as an RSS feed. -apply_rss_feed_warning1=This Space must be visible to the Guest user for the RSS feed to be publically viewable, you can Invite the Guest user using the -apply_rss_feed_warning2=view. -rss_feed=RSS Feed -rss_feed_link=RSS Feed Link - -# Export messages -export_info=Exports metadata and content from this or all Spaces. -export_from=Export From -package_name=Package Name -all_spaces_root=Complete Repository -current_space=Current Space -include_children=Include Children -include_self=Include this Space -run_export_in_background=Run export in background -export_error_info=If this option is selected the export will be performed in the background so the results may not appear immediately. You may also want to monitor the server console and log files for errors. - -# Import messages -import_info=Imports an Alfresco content package file into the repository. -import_package_description=Alfresco content package -run_import_in_background=Run import in background -import_error_info=If this option is selected the import will be performed in the background so the results may not appear immediately. You may also want to monitor the server console and log files for errors. - -# Edit Content messages -edit_file_title=Edit file -edit_file_prompt=To edit the file ''{0}'', click the link below and if asked select Save. -edit_download_complete=When the download is complete, click Close. -checkout_file_title=Check out file -checkout_you_may_want=You may want to check out this file to lock it and prevent other users from editing it. -checkout_hint1=Hint: When you check out a file a copy is made for you to work with. -checkout_hint2=When you have finished editing the copy you need to check it in to release the lock and allow others to work with the modified document. -checkout_want_to=to prevent the possibility of other users overwriting your changes. -checkout_warn=Note: You will lose any changes already made to this document. -local_copy_location=Local copy location -locate_content_upload=Locate and upload your document to the repository. - -# System Information and admin page messages -system_info=System Information -current_user=Current User -http_app_state=HTTP Application State -http_session_state=HTTP Session State -http_request_state=HTTP Request State -http_request_params=HTTP Request Parameters -http_request_headers=HTTP Request Headers -repository_props=Repository Properties -repository_patch_succeeded=Succeeded -repository_patch_failed=FAILED -system_props=System Properties -hide_details=Hide Details -show_details=Show Details -user_search_info=To find a user search for them using their first name, last name and/or user name. Alternatively to see all users click 'Show All', however, this may take some time if there are a lot of users in the system. -user_change_homespace_info=Selecting a new home space for a user will not remove the existing permissions on the original home space. You may wish to use the Manage Space Users dialog to modify permissions if they are no longer required on the original home space. - -# Content Wizard messages -add_content_dialog_title=Add Content Dialog -add_content_dialog_desc=This dialog helps you to add content to a space. -upload_content=Upload Content -properties=Properties -general=General -file_name=File Name -content_type=Content Type -content_format=Content Format -inline_editable=Inline Editable -locate_content=Locate content to upload -content_location=Location -uploaded_content=Uploaded Content -click_upload=Click upload -file_upload_success=''{0}'' was uploaded successfully. -modify_props_when_page_closes=Modify all properties when this page closes. -modify_props_when_wizard_closes=Modify all properties when this wizard closes. -modify_props_help_text=Rules applied to this content may require you to enter additional information. -content_finish_instruction=To add the content to this space click Finish. To review or change your selections click Back. -create_content_title=Create Content Wizard -create_content_desc=This wizard helps you to create a new document in a space. -create_content_step1_title=Step One - Specify name and select type -create_content_step1_desc=Specify the name and select the type of content you wish to create. -create_content_step2_title=Step Two - Enter Content -create_content_step2_desc=Enter your document content into the repository. -enter_content=Enter Content -select_type=Select Type -content=Content -text_content=Plain Text Content -html_content=HTML Content -xml_content=XML Content -create_xml_content_type_title=Create XML Content Type Wizard -create_xml_content_type_desc=Create XML Content Type -create_xml_content_type_step1_title=Upload an XML Schema -create_xml_content_type_step1_desc=Upload an XML Schema -create_xml_content_type_step2_title=Edit the XML Schema -create_xml_content_type_step2_desc=This is the generated XForm based on the schema provided. -edit_xml_schema=Edit XML Schema -template_type=Template Type -configure_presentation_templates=Configure Presentation Templates - -# Rule and Action Wizard messages -run_action_title=Run Action Wizard -run_action_desc=This wizard helps you run an action -run_action_step1_title=Step One - Select Actions -run_action_finish_instruction=To execute the action click Finish. To review or change your selections click Back. -create_rule_title=Create Rule Wizard -create_rule_desc=This wizard helps you create a new rule. -create_rule_step1_title=Step One - Select Conditions -create_rule_step2_title=Step Two - Select Actions -create_rule_step3_title=Step Three - Enter Details -create_rule_finish_instruction=To create the rule click Finish. To review or change your selections click Back. -edit_rule_title=Edit Rule Wizard -edit_rule_desc=This wizard helps you modify a rule. -edit_rule_finish_instruction=To update the rule click Finish. To review or change your selections click Back. -select_action=Select Action -select_an_action=Select an action... -select_a_type=Select a type... -action=Action -action_settings=Action Settings -set_action_values=Set action values -select_feature=Select required feature -version_notes=Version Notes -checkout_location=Check out location -destination=Destination -message=Message -category=Category -categories=Categories -change_category=Change Category -approve_flow=Approve Flow -approve_step_name=Name for approve step -move_or_copy=Choose whether you want to move or copy the content and also the location. -reject_flow=Reject Flow -want_reject_step=Do you want to provide a reject step? -reject_step_name=Name for reject step -required_format=Required format -details=Details -select_condition=Select Condition -select_a_condition=Select a condition... -condition=Condition -conditions=Conditions -condition_settings=Condition Settings -set_condition_values=Set condition values -select_checkout_prompt=Click here to select the check out location -condition_contains_desc=Enter the text pattern required, including any wildcards. The file name includes the file type extension when matching. -file_name_pattern=File name pattern -condition_contains_hints=Hints -condition_contains_hints_desc=Use zz* to match any name that begins with zz; use *.txt to match any text file; use *zz* to match any file name that contains zz anywhere including the beginning or end. -apply_to_sub_spaces=Apply rule to sub spaces -run_in_background=Run rule in background -rule_disabled=Disable rule -not=Not -click_set_and_add=Click to set values and add to list -click_add_to_list=Click to add to list -set_and_add_button=Set Values and Add -selected_conditions=Selected Rule Conditions -selected_actions=Selected Rule Actions -condition_has_aspect=Item has aspect ''{0}'' -condition_has_aspect_not=Item does not have aspect ''{0}'' -condition_is_subtype=Item is a subtype of ''{0}'' -condition_is_subtype_not=Item is not a subtype of ''{0}'' -condition_compare_mime_type=Item has a mimetype of ''{0}'' -condition_compare_mime_type_not=Item does not have a mimetype of ''{0}'' -condition_in_category=Item is in category ''{0}'' -condition_in_category_not=Item is not in category ''{0}'' -condition_compare_property_value=Name property matches ''{0}'' -condition_compare_property_value_not=Name property does not match ''{0}'' -action_add_features=Add aspect ''{0}'' -action_remove_features=Remove aspect ''{0}'' -action_specialise_type=Item is specialised to type ''{0}'' -action_simple_workflow={0} item to ''{1}'' if ''{2}'' action is taken. -action_link_category=Link to category ''{0}'' -action_transform=Copies content to ''{0}'' and transforms to ''{1}'' -action_transform_image=Copies image to ''{0}'' and transforms to ''{1}'' using option ''{2}'' -action_copy=Copy to ''{0}'' -action_move=Move to ''{0}'' -action_mail=Send email to ''{0}'' -action_mail_template=Use Template -action_check_in=Check in content as ''{0}'' with comment ''{1}'' -action_check_out=Check out content to ''{0}'' -action_set_property_value=Sets property ''{0}'' -action_import=Imports to ''{0}'' -action_script=Executes script ''{0}'' -action_script_select=Select a script to execute -not_condition_result=Check the item does not match the criteria above -space=Space -import_to=Import To -encoding=Encoding -encoding_utf8=UTF-8 -rule_type=Rule Type -rule_background_info=If this option is selected the rule will execute in the background so the results may not appear immediately. -select_recipients=Search for email recipients by Name or Group -selected_recipients=Selected email recipients -message_recipients=Message Recipients -email_message=Email message -insert_template=Insert Template -discard_template=Discard Template - -# Create Space Wizard messages -create_space_title=Create Space Wizard -create_space_desc=This wizard helps you to create a new space. -create_space_step1_title=Step One - Starting Space -create_space_step1_desc=Choose how you want to create your space. -create_space_step2_title=Step Two - Space Options -create_space_step2_desc=Select space options. -create_space_step3_title=Step Three - Space Details -create_space_step3_desc=Enter information about the space. -create_space_finish_instruction=To close this wizard and create your space click Finish. To review or change your selections click Back. -scratch=Scratch -an_existing_space=An existing space -a_template=A template -creating_from=Creating From -save_as_template=Save As Template -template_name=Template Name -select_a_template=Select a template... -select_a_script=Select a script... -starting_space=Starting Space -space_options=Space Options -space_details=Space Details -how_to_create_space=How do you want to create your space? -from_scratch=From scratch -based_on_existing_space=Based on an existing space -using_a_template=Using a template -existing_space=Existing Space -copy_existing_space=Copy existing space -structure=Structure -structure_contents=Structure and contents -space_copy_note=Note: Any content rules for spaces will also be copied. -space_type=Space Type -space_type_create=Select the type of space you want to create. -container=Folder Space -container_desc=A place for keeping and organizing documents and other spaces. -forums_desc=A place to discuss content with other users. -space_type_note=Note: If you can only see one type of space then other space types may not be enabled. See your System Administrator for further help. -template_space=Template Space -select_template=Select the template you want to use. - -# Create Website Wizard messages -create_website=Create Website -create_website_title=Create Website Wizard -create_website_desc=This wizard helps you create a new website space. -website_details=Website Details -create_website_step1_title=Step One - Website Details -create_website_step1_desc=Enter the information about the website. -create_website_finish_instruction=To close this wizard and create your website space click Finish. To review or change your selections click Back. - -# Browse Website and Sandboxes messages -title_browse_website=Browse Website Sandboxes -website_info=Use this view to browse the staging area and user sandboxes for a website. -staging_sandbox=Staging Sandbox - -# New User Wizard messages -new_user_title=New User Wizard -new_user_title_edit=Edit User Wizard -new_user_desc=This wizard helps you to add a user to the repository. -new_user_desc_edit=This wizard helps you modify a user in the repository. -new_user_step1_title=Step One - Person Properties -new_user_step1_desc=Enter information about this person. -new_user_step2_title=Step Two - User Properties -new_user_step2_desc=Enter information about this user. -new_user_finish_instruction=To add the user to this space click Finish. To review or change your selections click Back. -person_properties=Person Properties -user_properties=User Properties -first_name=First Name -last_name=Last Name -email=Email -company_id=Company ID -home_space_location=Home Space Location -home_space_name=Home Space Name - -# Trashcan messages -title_deleted_items=Deleted Items -title_delete_all=Delete All Items -title_recover_all=Recover All Items -title_recover_listed=Recover Listed Items -title_delete_listed=Delete Listed Items -title_delete_item=Delete Item -title_recover_item=Recover Item -title_recovery_report=Recovery Report -deleted_items=Deleted Items -manage_deleted_items=Manage Deleted Items -manage_deleted_items_description=Remove or recover previously deleted items -recover_all_items=Recover All Items -delete_all_items=Delete All Items -deleted_items_info=Use the Search to find deleted items by name or content and use the filters to reduce the list. -original_location=Original Location -deleted_date=Date Deleted -deleted_user=Deleted by User -recover=Recover -clear_search_results=Clear Search Results -search_deleted_items_name=Search by Name -search_deleted_items_text=Search by Content -deleted_items_for=for ''{0}'' -delete_item=Delete Item -delete_item_info=Permanently delete an item from the deleted file store -delete_item_confirm=Are you sure you want to permanently delete \"{0}\" from the deleted file store? The item cannot be recovered once this action has been performed. -recover_item=Recover Item -recover_item_info=Recover an item from the deleted file store -recover_item_confirm=Are you sure you want to recover \"{0}\" from the deleted file store? -delete_all_items_info=Permanently delete all files and spaces from the deleted file store -delete_all_items_confirm=Are you sure you want to permanently delete all files and spaces from the deleted file store? The items cannot be recovered once this action has been performed. -recover_all_items_info=Recover all files and spaces from the deleted file store -recover_all_items_confirm=Are you sure you want to recover all the deleted files and spaces from the deleted file store? -delete_listed_items=Delete Listed Items -delete_listed_items_info=Permanently delete the listed files and spaces from the deleted file store -delete_listed_items_confirm=Are you sure you want to permanently delete the following deleted files and spaces from the deleted file store? The items cannot be recovered once this action has been performed. -recover_listed_items=Recover Listed Items -recover_listed_items_info=Recover the listed files and spaces from the deleted file store -recover_listed_items_confirm=Are you sure you want to recover the following deleted files and spaces from the deleted file store? -recovered_item_success=The item \"{0}\" has been successfully recovered. -recovered_item_parent=Failed to recover the item \"{0}\" as the parent folder is missing, please select a new folder destination. -recovered_item_parent_short=Parent folder missing -recovered_item_permission=Failed to recover the item \"{0}\" as you do not have the appropriate permissions to restore the item to the parent folder, please select a new folder destination. -recovered_item_permission_short=No permissions to write -recovered_item_integrity=Failed to recover the item \"{0}\" as there is now an item in the parent folder with the same name, please select a new folder destination. -recovered_item_integrity_short=Item with same name exists -recovered_item_failure=Failed to recover the item \"{0}\" due to error: {1} -recovered_item_failure_short=Failed -delete_item_success=The item \"{0}\" has been permanently deleted. -title_deleted_item_details=Deleted Item Details -deleteditem_details_description=Details of the deleted item -alternative_destination=You may select a destination where you wish the recovered items to be placed. If you do not select a destination, the original location of the item is used. Recovery of an item may fail if the destination does not exist or you do not have permission to add items there. -user_filter_who=Who -user_filter_all=All -user_filter_user=User -date_filter_when=When -date_filter_all=All -date_filter_today=Today -date_filter_week=Last 7 days -date_filter_month=Last 30 days -recovery_report=Recovered Items Report -recovery_report_info=The results of recovering the selected items -recovery_report_success=The following items were recovered successfully -recovery_report_failed=The following items failed to recover -recovery_report_reason=Failure Reason - -# My Alfresco messages -my_alfresco=My Alfresco -title_my_alfresco=My Alfresco -dashboard_info=My Alfresco Dashboard -dashboard_description=Configure this view and build your personal Alfresco dashboard -configure=Configure -error_dashboard=An error occurred in one of the dashlets. - -# My Alfresco Layout Manager wizard messages -configure_dashboard_title=Configure Dashboard Wizard -configure_dashboard_desc=This wizard helps you configure your dashboard layout and contents -step_layout=Layout -configure_dashboard_step1_title=Step One - Select Layout -configure_dashboard_step1_desc=Choose the layout and number of columns for your dashboard. -step_columns=Components -configure_dashboard_step2_title=Step Two - Select Components -configure_dashboard_step2_desc=Select the components for your dashboard and add them to the columns. -configure_dashboard_finish_instruction=To save the dashboard configuration click Finish. To review or change your selections click Back. -select_layout=Select the style of layout for your dashboard. Changing your existing dashboard layout to another with less columns will result in the additional columns being removed. -select_column=Select the column to configure -dashlet_list=Available Components -dashlet_btn_select=Add -dashlet_btn_remove=Remove -selected_dashlets=Selected Components -dashboard_column=Column -column_max_components=this column can display {0} components - -# My Alfresco Layouts messages -layout_single_label=Single Column -layout_single_desc=This layout displays components in a single column the full width of the page -layout_narrow_left_label=Two Column Narrow Left -layout_narrow_left_desc=This layout display components in two columns with a narrow left hand column -layout_narrow_right_label=Two Column Narrow Right -layout_narrow_right_desc=This layout display components in two columns with a narrow right hand column -layout_three_column_label=Three Column -layout_three_column_desc=This layout displays components across three columns of equal width - -# My Alfresco Dashlet components messages -dashlet_gettingstarted_label=Getting Started -dashlet_gettingstarted_desc=Displays helpful information for getting started with the Alfresco web-client -dashlet_mydocuments=My Documents -dashlet_mydocuments_desc=Displays a list of the documents in my home space -dashlet_checkedoutdocs=My Checked Out Documents -dashlet_checkedoutdocs_desc=Displays a list of the documents checked out to me -dashlet_myimages=My Images -dashlet_myimages_desc=Displays a 3 column thumbnail list of the images in my home space -gettingstarted_commontasks=Common Tasks -gettingstarted_browse=Browse items in your home space -gettingstarted_browse_desc=From the toolbar click My Home to display a list of items in the space. -gettingstarted_createspace=Create a space in your home space -gettingstarted_createspace_desc=Navigate to your home space. In the space info area, from the menu under Create, click Create Space and enter information about the space. -gettingstarted_addcontent=Add content to your home space -gettingstarted_addcontent_desc=Navigate to your home space. In the space info area, click Add Content and enter information about the content to be uploaded. -gettingstarted_createcontent=Create content in your home space -gettingstarted_createcontent_desc=Navigate to your home space. In the space info area, click Create Content under Create and enter information about the content to be created. -gettingstarted_demonstration=Demonstration -gettingstarted_demonstration_desc=Watch a demonstration of how Alfresco can be used to create a marketing launch. -gettingstarted_featuretour=Feature Tour -gettingstarted_featuretour_desc=Take a tour of some of the key features in Alfresco. -gettingstarted_onlinehelp=Online Help -gettingstarted_onlinehelp_desc=Click the help icon to display Alfresco Help topics. - -# User Console and Settings messages -title_user_console=User Options -title_edit_user_details=Edit User Details -user_console=User Options -user_console_info=User Options -user_console_description=Use this page to change your options and settings -my_details=My Details -general_pref=General Preferences -change_my_password_description=Use this view to change your password -change_my_password_instructions=Enter your new password. -old_password=Old Password -new_password=New Password -edit_user_details=Edit User Details -edit_user_details_description=Use this view to change your user details and email address -start_location=Start Location - -# Delete Space Dialog messages -select_delete_operation=What do you want to delete? -delete_op_all=This space and all its contents. Note: Rules will also be deleted. -delete_op_files=Only the files within this space. -delete_op_folders=Only the folders within this space. -delete_op_contents=Files and folders within this space. - -# Email users dialog -email_space_users=Email Space users -email_space_users_desc=Send an email to the users and groups assigned to this space. - -# Workflow messages -modify_workflow_props=Modify Properties of Simple Workflow -name_approve_step=Name for approve step -name_reject_step=Name for reject step -select_reject_step=Do you want to provide a reject step? -choose_copy_move_location=Choose whether you want to move or copy the content and also the location. -start_workflow=Start Workflow -start_workflow_wizard=Start New Workflow Wizard -start_workflow_desc=This wizard helps you start a workflow for an item in the repository. -available_workflows=Available workflows -step_choose_workflow=Choose Workflow -start_workflow_choose_title=Choose Workflow -start_workflow_choose_desc=Choose the workflow you want to start -step_workflow_options=Workflow Options -start_workflow_options_title=Workflow Options -start_workflow_options_desc=Select options for the workflow -start_workflow_finish_instruction=To start the workflow press Finish. To review or change your selections click Back. -start_workflow_no_metadata=There is no metadata to collect for this particular workflow. -users_and_roles=Users and their Roles -resources=Resources -manage_task=Manage Task -manage_task_title=Manage Task -manage_task_desc=This dialog allows the task to be managed. -view_completed_task_title=View Completed Task -view_completed_task_desc=This dialog allows the completed task details to be viewed. -task_properties=Task Properties -id=Id -status=Status -completed=Completed -source=Source -priority=Priority -my_tasks_todo_title=My Tasks To Do -my_tasks_todo_desc=List of your tasks still to complete -my_tasks_completed_title=My Completed Tasks -my_tasks_completed_desc=List of your completed tasks -due_date=Due Date -completed_on=Completed on -outcome=Outcome -reassign=Reassign -cancel_workflow=Cancel Workflow -cancel_workflow_info=To cancel this workflow, click OK. -cancel_workflow_confirm=Are you sure you want to cancel the \"{0}\" workflow? -error_cancel_workflow=Unable to cancel the workflow due to system error: -reassign_task_title=Reassign Task -reassign_task_desc=This dialog allows you to reassign a task. -reassign_select_user=Select the user to assign the task to, then press OK. -error_reassign_task=Unable to reassign the task due to system error: -part_of_workflow=Part of Workflow -initiated_by=Initiated by -start_date=Start date -add_resource=Add Resource -view_properties=View Content Properties -edit_properties=Edit Content Properties - -# Admin Console messages -title_admin_console=Administration Console -admin_console=Administration Console -admin_description=Use this view to perform system administration functions. -admin_limited_license=Licensed: {0} license granted to {1} and limited to {3} days expiring {4,date,short} ({5} days remaining - issued on {2,date,short}). -admin_unlimited_license=Licensed: {0} license granted to {1} and does not expire (issued on {2,date,short}). -admin_invalid_license=Licensed: LICENSE INVALID - Alfresco Repository restricted to read-only capability. - -# UI Page Titles -title_about=About Alfresco -title_login=Alfresco Web Client - Login -title_relogin=Alfresco Web Client - Logged Out -title_error=Alfresco Web Client - System Error -title_browse=Alfresco Web Client -title_inviteusers_invite=Invite Users - Invite -title_inviteusers_notify=Invite Users - Notify -title_invitecontentusers_invite=Invite Content Users - Invite -title_invitecontentusers_notify=Invite Content Users - Notify -title_change_user_roles=Change User Roles -title_remove_invited_user=Remove Invited User -title_advanced_search=Advanced Search -title_checkin_file=Check In File -title_checkout_file=Check Out File -title_checkout_file_link=Check Out File Download -title_delete_file=Delete File -title_delete_rule=Delete Rule -title_delete_user=Delete User -title_delete_space=Delete Space -title_file_details=Document Details -title_file_preview=Preview In Template -title_edit_categories=Edit Categories -title_edit_doc_props=Edit Document Properties -title_edit_link_props=Edit Link Properties -title_edit_file=Edit File -title_edit_html_inline=Edit HTML File Inline -title_edit_text_inline=Edit Text File Inline -title_edit_simple_workflow=Edit Simple Workflow -title_edit_space=Edit Space Details -title_rules=Space Rules -title_space_details=Space Details -title_apply_template=Apply Template -title_system_info=System Information -title_undo_checkout=Undo Check Out -title_update_file=Update File Content -title_users=User Management -title_invited_users=Manage Invited Users -title_content_users=Manage Content Users -title_add_content=Add Content -title_create_content=Create New Content -title_create_content_props=Create New Content - Properties -title_create_content_summary=Create New Content - Summary -title_action_add_feature=Add Feature Action -title_action_remove_feature=Remove Feature Action -title_action_checkin=Check In Action -title_action_checkout=Check Out Action -title_action_copy=Copy Action -title_action_move=Move Action -title_action_script=Script Action -title_action_import=Import Action -title_action_email=Email Action -title_action_link_category=Link Category Action -title_action_simple_workflow=Simple Workflow Action -title_action_transform=Transform Action -title_action_transform_image=Transform Image Action -title_action_specialise_type=Specialise Type Action -title_condition_contains_text=Contains Text Condition -title_condition_has_mimetype=Has Mimetype Condition -title_condition_in_category=In Category Condition -title_condition_is_subtype=Is Subtype Condition -title_condition_has_aspect=Has Aspect Condition -title_new_user_person_props=User - Person Properties -title_new_user_user_props=User - User Properties -title_new_user_summary=User - Summary -title_export=Export -title_import=Import -title_admin_store_browser=Alfresco Store Browser -title_admin_node_browser=Alfresco Node Browser -title_admin_search_results=Node Browser Search Results -title_forums=Forum Space -title_forum=Forum -title_topic=Topic -title_delete_forums_space=Delete Forum Space -title_delete_forum_space=Delete Forum -title_delete_topic_space=Delete Topic -title_delete_post=Delete Post -title_create_forums=Create Forum Space -title_create_forum=Create Forum -title_forums_details=Forum Space Details -title_forum_details=Forum Details -title_create_topic=Create Topic -title_create_discussion=Create Discussion -title_topic_details=Topic Details -title_create_post=Post Message -title_create_reply=Create Reply -title_edit_forums=Edit Forum Space Details -title_edit_forum=Edit Forum Details -title_edit_topic=Edit Topic Details -title_edit_post=Edit Post -title_noaccess=No Access - -# UI Error messages -error_generic=A system error happened during the operation: {0} -error_noderef=Unable to find the repository item referenced by Id: {0} - the record has probably been deleted from the database. -error_deleted_folder=The folder item referenced by Id: {0} - has been deleted from the database. The system has changed your folder location as the folder you were in no longer exists. -error_homespace=The Home Space node referenced by Id: {0} cannot be found. It may have been deleted from the database. Please contact your system administrator. -error_search=Search failed due to system error: {0} -error_exists=A Space or File with that name already exists: {0} -error_delete_space=Unable to delete Space due to system error: -error_delete_file=Unable to delete File due to system error: -error_checkout=Unable to check out Content Node due to system error: -error_update=Unable to update Content Node due to system error: -error_cancel_checkout=Unable to cancel check out of Content Node due to system error: -error_checkin=Unable to check in Content Node due to system error: -error_paste=Unable to paste item due to system error: -error_login_user=Unable to login - unknown username/password. -error_login_missing=Must specify username and password. -error_delete_rule=Unable to delete Rule due to system error: -error_actions=Failed to run Actions due to error: {0} -error_rule=Failed to create Rule due to error: {0} -error_space=Failed to create new space due to error: {0} -error_person=Failed to create Person due to error: {0} -error_delete_user=Failed to delete User due to error: {0} -error_delete_user_object=Unable to delete the User object associated with the Person. This is not an error if an external authentication mechanism such as NTLM was previously active. -error_remove_user=Failed to remove User due to error: {0} -error_password_match=Please ensure that both password fields contain the same value. -error_property=Property ''{0}'' is not available for this node -error_create_space_dialog=Please correct the errors below then click Create Space. -error_create_forums_dialog=Please correct the errors below then click Create Forum Space. -error_create_forum_dialog=Please correct the errors below then click Create Forum. -error_create_topic_dialog=Please correct the errors below then click Create Topic. -error_create_post_dialog=Please correct the errors below then click Post. -error_create_reply_dialog=Please correct the errors below then click Reply. -error_create_category_dialog=Please correct the errors below then click New Category. -error_create_group_dialog=Please correct the errors below then click Create Group. -error_dialog=Please correct the errors below then click OK. -error_wizard=Please correct the errors below then click Finish. -error_update_category=Failed to update category due to system error: {0} -error_update_simpleworkflow=Failed to update simple workflow due to system error: {0} -error_workflow_approve=Failed to approve the document due to system error: {0} -error_workflow_reject=Failed to reject the document due to system error: {0} -error_aspect_classify=Failed to apply the ''classifiable'' aspect to the document due to system error: {0} -error_aspect_classify_space=Failed to apply the ''classifiable'' aspect to the space due to system error: {0} -error_aspect_versioning=Failed to apply the ''versionable'' aspect to the document due to system error: {0} -error_aspect_inlineeditable=Failed to apply the ''inlineeditable'' aspect to the document due to system error: {0} -error_content_missing=The node''s content is missing: \n node: {0} \n reader: {1} \nPlease contact your system administrator. -error_export=Failed to execute export: {0} -error_import=Failed to execute import: {0} -error_import_no_file=Can not find an ACP file to import! -error_import_empty_file=You can not import an empty ACP file! -error_import_all=Please correct the import errors below then click OK. -error_export_all=Please correct the export errors below then click OK. -error_save_search=Failed to save search due to error: {0} -error_restore_search=Failed to restore saved search due to error: {0} -error_shortcut_permissions=Unable to navigate to the item as it cannot be read by this user. Another user may have modified the permission. - -# Confirmations -return_to_application=Return to application -delete_space_info=To remove this space and all of its contents, click OK. -delete_space_confirm=Are you sure you want to delete \"{0}\" and all its contents? -delete_forums_info=To remove this forum space and its contents, click OK. -delete_forum_info=To remove this forum and its topics, click OK. -delete_forum_confirm=Are you sure you want to delete \"{0}\" and all its topics? -delete_topic_info=To remove this topic and its posts, click OK. -delete_topic_confirm=Are you sure you want to delete \"{0}\" and all its posts? -delete_post_info=To remove this post from the topic, click OK. -delete_post_confirm=Are you sure you want to delete the post from \"{0}\"? -delete_file_info=To remove this file and any previous versions, click OK. -delete_file_confirm=Are you sure you want to delete \"{0}\" and all previous versions? -delete_rule_info=To remove this rule from the space, click Yes. -delete_user_info=To delete this user from the system, click Yes. -delete_rule_confirm=Are you sure you want to delete \"{0}\"? -delete_user_confirm=The User will no longer be able to access the system. Are you sure you want to delete user \"{0}\"? -remove_invited_user_confirm=The User will no longer be able to access the documents and folders in this space. Are you sure you want to remove user \"{0}\"? -remove_content_user_confirm=The User will no longer be able to access this content. Are you sure you want to remove user \"{0}\"? -delete_companyroot_confirm=WARNING: This folder is a special folder accessed by all Users! Please be sure that you wish to delete this folder. It may cause System Errors if you remove it. - -# Status Messages -status_space_created=Successfully created space ''{0}''. -status_space_deleted=Successfully deleted space ''{0}''. -status_space_updated=Successfully updated space ''{0}''. - -# Validation Messages -validation_mandatory={0} is a mandatory field. -validation_string_length={0} must be between {1} and {2} characters in length. -validation_regex={0} is invalid. -validation_regex_not_match={0} is invalid. -validation_numeric_range={0} must be between {1} and {2}. +# I18N message properties + +# Date Pattern +date_pattern=d MMMM yyyy +date_time_pattern=d MMMM yyyy HH:mm +time_pattern=HH:mm + +# General UI +product_name=Alfresco +view_description=This view allows you to browse the items in this space. +search_description=This view allows you to see the results from your search. +checkinfile_description=Check in your working copy for other team members to work with. +checkoutfilelink_description=Edit the checked out file, undo the check out or carry on working. +checkoutfile_description=Enter information about the check out. +documentdetails_description=View the details about the content. +linkdetails_description=View the details about the link object. +previewdocument_description=Preview the content or space within a Template. +spacedetails_description=View the details about the space. +undocheckoutfile_description=Cancel the check out of a document and discard any changes. +updatefile_description=Update a document on the repository with content from your computer. +editfile_description=Edit the content of the file. +editfileinline_description=Edit the content of the document, then click Save. +createfile_description=Enter new content. +manageusers_description=Manage the users of the repository. +manage_invited_users_description=Manage the permissions you have granted to users who access your space. +manage_content_users_description=Manage the permissions you have granted to users who access your content. +modify_user_roles_description=Modify the permissions granted to a user for accessing your space. +modify_content_user_roles_description=Modify the permissions granted to a user for accessing your content. +advancedsearch_description=Perform a more detailed search of the repository. +edit_content_description=Modify the content properties then click OK. +view_content_description=View the content properties. +editcategory_description=Set the category for the document then click OK. +editcategory_space_description=Set the category for the space then click OK. +editworkflow_description=Modify the simple workflow properties then click OK. +editspace_description=Modify the space properties then click OK. +editlink_description=Modify the link object properties then click OK. +create_space_description=Enter information about the new space then click Create Space. +space_rules_description=This view shows you all the rules to be applied to content in this space. +warning_inline=This is only recommended for HTML or plain text documents. +categories_description=This view allows you to browse and modify the categories hiearchy. +new_category_description=Enter information about the new Category then click Create Category. +status_message_default=No messages. +no_icons_found=No icons found + +# UI Component messages +yes=Yes +no=No +kilobyte=KB +megabyte=MB +gigabyte=GB +locked_you=Item locked by you +locked_user=Item locked by user +wizard_errors=Please correct the errors below. +last_page=Last Page +next_page=Next Page +prev_page=Previous Page +first_page=First Page +page_info=Page {0} of {1} +go_up=Go Up +ok=OK +go=Go +to=To +from=From +options=Options +other_options=Other Options +local=Local +inherited=Inherited +search=Search +advanced_search=Advanced Search +value_not_set=not set +clear=Clear Results +results_contains=Results for ''{0}''. +results_contains_filter=Results for ''{0}'' in ''{1}''. +details_view=Details View +view_icon=Icon View +view_browse=Browse View +create_options=Create +more_options=More... +more_actions=More Actions +more_options_space=More Actions for this Space +more_options_file=More Actions for this Document +select_space_prompt=Click here to select a Space +select_existing_space_prompt=Click here to select an existing Space +select_home_space_prompt=Click here to select the Home Space location +select_category_prompt=Click here to select a Category +select_destination_prompt=Click here to select the destination +add_new=Add New +change=Change +set=Set +no_categories_applied=This document does not yet have any categories applied. +has_following_categories=This document has the following categories applied... +no_categories_applied_space=This space does not yet have any categories applied. +has_following_categories_space=This space has the following categories applied... +moved=moved +copied=copied +document_action=The document will be {0} to ''{1}'' if the ''{2}'' action is taken. +clipboard=Clipboard +recent_spaces=Recent Spaces +shortcuts=Shortcuts +company_home=Company Home +my_home=My Home +guest_home=Guest Home +new_search=New Search +search_results=Search Results +search_detail=Search for \"{0}\" results shown below +close_search=Close Search +browse_spaces=Browse Spaces +browse_content=Content Items +location=Location +toggle_shelf=Hide or Show the Shelf +shelf=Shelf +actions=Actions +view=View +view_details=View Details +view_details_file=View Details for file +change_details=Change Details +update=Update +cut=Cut +copy=Copy +paste=Paste +remove=Remove +change_roles=Change Roles +change_user_roles=Change User Roles +paste_item=Paste Item +paste_link=Paste As Link +paste_all=Paste All +remove_item=Remove Item +remove_all=Remove All +close=Close +invite=Invite +invite_user=Invite User +filter_contents=Filter Contents +users=Users +groups=Groups +resetall=Reset All +content_rules=Content Rules +view_in_browser=View In Browser +view_in_webdav=View in WebDAV +view_in_cifs=View in CIFS +download_content=Download Content +details_page_bookmark=External Access URL +noderef_link=Alfresco Node Reference +links=Links +create_shortcut=Create Shortcut +navigation=Navigation +next_item=Next Item +previous_item=Previous Item +cancel=Cancel +upload=Upload +homespace=Home Space +network_folder=Open Network Folder +other_action=Run Action +information=Information +move=Move +type=Type +aspect=Aspect +workflow=Workflow +rules=Rules +system_error=System Error +login=Login +templates=Templates +template=Template +rss_template=RSS Template +select_button=Select... +select_items=Select items +select_an_item=Select an item +selected_items=Selected Items +add_to_list_button=Add to List +none=None +no_selected_items=No selected items. +search_select_item=Search for and select an item. +search_select_items=Search for and select items. +search_minimum=Not enough information was entered to perform a search, at least one value must be entered or a location selected to search within. Text fields require a minimum of {0} characters. +filter=Filter +choose_icon=Choose icon +security=Security +all_formats=All Formats +rules_count=Number of rules applied to this Space +working_copy_document=Working Copy +copy_of=Copy of +link_to=Link to +icon=Icon +lock=Lock +unlock=Unlock +items_per_page=Items Per Page +raise_issue=Raise an Issue +click_to_set_date=Click to set a date +today=Today +reset=Reset + +# Properties +username=User Name +joindate=Join Date +roles=Roles +help=Help +name=Name +password=Password +confirm=Confirm +path=Path +description=Description +created=Created +modified=Modified +created_date=Created Date +modified_date=Modified Date +size=Size +title=Title +author=Author +date=Date +mimetype=Format + +# Repo permission display labels +# Note - these come from the server, the english translation is generally the same +Administrator=Administrator +Consumer=Consumer +Read=Consumer +Coordinator=Coordinator +Collaborator=Collaborator +Contributor=Contributor +Editor=Editor +All=All + +# Actions +delete=Delete +edit=Edit +checkin=Check In +checkout=Check Out +checkout_document=Check out this document +undocheckout=Undo Check Out +delete_space=Delete Space +delete_file=Delete File +delete_rule=Delete Rule +delete_user=Delete User +remove_user=Remove User +create_space=Create Space +add_content=Add Content +create_content=Create Content +create_xml_content_type=Create XML Content Type +add_multiple_files=Add Multiple Files +import_directory=Import Directory +advanced_space_wizard=Advanced Space Wizard +create_rule=Create Rule +reapply_rules=Reapply Rules +reapply_rules_success=The rules have been successfully reapplied. +ignore_inherited_rules=Ignore Inherited Rules +include_inherited_rules=Include Inherited Rules +inherited_rules_being_ignored=Inherited rules are being ignored. +manage_rules=Manage Content Rules +manage_users=Manage System Users +manage_groups=Manage User Groups +manage_invited_users=Manage Space Users +manage_content_users=Manage Content Users +modify_user_roles=Modify User Roles for +modify=Modify +logout=Logout +add=Add +node_browser=Node Browser +reset_config=Reset Config Service +save=Save +user_details=User Details +language=Language +export=Export +import=Import +take_ownership=Take Ownership +create_forums=Create Forum Space +create_forum=Create Forum +create_topic=Create Topic +create_post=Create Post +create_reply=Post Reply +delete_forums=Delete Forum Space +delete_forum=Delete Forum +delete_topic=Delete Topic +delete_post=Delete Post +post_to_topic=Post to Topic +reply=Reply +edit_post=Edit Post +reply_to=Reply to +post_reply=Post Reply + +# Login page message +login_details=Enter Login details +login_err_password_length=Password must be between {0} and {1} characters in length. +login_err_password_chars=Password can only contain characters or digits. +login_err_username_length=Username must be between {0} and {1} characters in length. +login_err_username_chars=Username can only contain characters or digits. +loggedout_details=You have been logged out of Alfresco. +relogin=Re-login to Alfresco +no_access=You have no access to Alfresco. +no_cookies=Cookies must be enabled in your browser for the Alfresco Web-Client to function correctly. +user_err_user_name=User ID cannot contain the characters: {0} + +# Browse list messages +no_space_items=No items to display. Click the ''{0}'' action to create a space. +no_content_items=No items to display. To add an existing document click ''{0}'' action. To create an HTML or Plain Text file click ''{1}'' action. + +# Advanced Search messages +look_in=Look in location +look_for=Look for +all_spaces=All Spaces +specify_space=Specify Space +include_child_spaces=Include child spaces +show_results_for=Show me results for +all_items=All Items +file_names_contents=File names and contents +file_names=File names only +space_names=Space names only +show_results_categories=Show me results in the categories +include_sub_categories=Include sub-categories +also_search_results=More search options +additional_options=Additional options +save_new_search=Save New Search +save_edit_search=Save Modified Search +saved_searches=My Saved Search Options +title_save_search=Save Search Query +save_search_description=Save a search query for use again later +search_props=Saved Search Properties +select_saved_search=Select a Saved Search... +saved_search_warning=This operation will attempt to overwrite the existing saved search ''{0}'' +user_searches=Your Searches +global_searches=Public Searches +save_search_global=Save as a public search available to all users. +folder_type=Folder Type + +# Forum messages +forums=Forum Space +forum=Forum +browse_forums=Browse Forum Spaces and Forums +browse_topics=Browse Topics +browse_posts=Browse Posts +forums_info=This view allows you to browse forum spaces and forums. +forum_info=This view allows you to browse topics in this forum. +topic_info=This view allows you to browse posts in this topic. +no_forums=No forum spaces or forums to display. Click the ''Create Forum Space'' action to create a forum space or ''Create Forum'' action to create a forum. +no_topics=No topics to display. Click the ''Create Topic'' action to create a topic. +no_posts=No posts to display. Click the ''Post to Topic'' action to create a post. +topic=Topic +topics=Topics +post=Post +posted=Posted +create_forums_description=Enter information about the new forum space then click Create Forum Space. +create_forum_description=Enter information about the new forum then click Create Forum. +create_topic_description=Enter information about the new topic then click Create Topic. +create_post_description=Enter the content of the message then click Post. +create_reply_description=Enter message text to reply then click Reply. +modify_forums_properties=Modify Forum Space Properties +forums_props=Forum Space Properties +modify_forum_properties=Modify Forum Properties +forum_props=Forum Properties +topic_props=Topic Properties +modify_topic_properties=Modify Topic Properties +create_forums_finish=To create the forum space click Create Forum Space. +create_forum_finish=To create the forum click Create Forum. +create_topic_finish=To create the topic click Create Topic. +create_post_finish=To create the post click Post. +create_reply_finish=To create the reply click Reply. +forums_details_description=View details about the forum space. +forum_details_description=View details about the forum. +topic_details_description=View details about the topic. +bubble_view=Bubble View +replies=Replies +on=On +reply_message=Reply Message +edit_forums_description=Modify the forum space properties then click OK. +edit_forum_description=Modify the forum properties then click OK. +edit_topic_description=Modify the topic properties then click OK. +edit_post_description=Modify the message then click OK. +edit_post_finish=To save the message click Post. +start_discussion=Start Discussion +discuss=View Discussions +discussion_for={0} discussion + +# Common Wizard messages +steps=Steps +summary=Summary +summary_desc=The information you entered is shown below. +default_instruction=To continue click Next. +next_button=Next +back_button=Back +finish_button=Finish +cancel_button=Cancel +clear_button=Clear +you_may_want=You may want to +summary_step_description=Shows a summary of the information entered. + +# Category Management messages +title_categories_list=Categories +add_category=Add Category +edit_category=Edit Category +delete_category=Delete Category +category_icons=Categories +category_details=Details +category_management=Category Management +title_create_category=Create New Category +new_category=New Category +category_props=Category Properties +items=Items +title_delete_category=Delete Category +delete_category_warning=This category has {0} existing document(s) linked to it. +delete_category_info=To remove this category and all it's sub-categories, click Delete. +delete_category_confirm=Are you sure you want to delete category \"{0}\" and all sub-categories? +title_edit_category=Edit Category +edit_category_description=Edit the information for this category. + +# Groups Management messages +title_groups_list=Groups Management +groups_management=Groups Management +groups_description=Manage the members of a group, create new groups or remove existing groups. +new_group=Create Group +new_sub_group=Create Sub-Group +edit_group=Edit Group +delete_group=Delete Group +add_user=Add User +group_icons=Groups +group_details=Details +root_groups=Root Groups +group_filter_children=Children +group_filter_all=All +title_create_group=Create Group +new_group_description=Enter information about the new Group then click Create Group. +group_props=Group Properties +identifier=Identifier +create_group_warning=The Identifier for a Group cannot be changed once it has been set. +title_delete_group=Delete Group +delete_group_warning=This group has {0} sub-group(s) or user(s) attached to it. +delete_group_info=To delete this Group from the system and remove all members from it, click Delete. +delete_group_confirm=Once the group is removed from the system it will no longer be accessable. Are you sure you want to delete Group \"{0}\" and remove all users from it? +title_add_user_group=Add User to Group +add_user_group_description=Add an existing User to a Group +select_users=Select Users to add to this Group +selected_users=Selected Users +groups_err_group_name=Group ID cannot contain the characters: {0} +groups_err_exists=A group ID with the same name already exists, group identifiers must be unique. + +# Invite Users Wizard messages +invite_title=Invite Users Wizard +invite_desc=This wizard helps you to give other users access to your space. +invite_step1_title=Step One - Invite Users +invite_step1_desc=Select the users and roles they will play in this space. +invite_step2_title=Step Two - Notify Users +invite_step2_desc=Notify the selected users. +i_want_to=I want to... +invite_step_1=Invite Users +invite_step_2=Notify Users +invite_all=Invite All users as guests +invite_users=Specify Users/Groups and their roles +specify_usersgroups=Specify Users/Groups +select_usersgroups=Select user/group and their role(s) +select_role=Select role +selected_usersgroups=Selected users/groups and their role(s) +selected_roles=Selected roles +click_add=Click Add +role=Role +send_email=Do you want to send an email to notify the invited users? +subject=Subject +body=Body +automatic_text=Automatic text +invited_to=You have been invited to ''{0}'' by {1}. +invite_role=You will have the role of: {0} +invite_finish_instruction=To close this wizard and apply your changes click Finish. To review or change your selections click Back. +remove_invited_user_info=To remove an invited user from this space, click Yes. +add_role=Add Role +space_owner=User ''{0}'' is the current owner of this space. +users_and_groups=Users and Groups +authority=Username + +# Invite Content Users Wizard messages +invite_content_title=Invite Content Users Wizard +invite_content_desc=This wizard helps you to give other users access to your content. +invite_content_step1_desc=Select the users and roles they will play for this content. +remove_content_user_info=To remove an invited user from this content, click Yes. +content_owner=User ''{0}'' is the current owner of this content. + +# System Users messages +create_user=Create User +change_password=Change Password +title_change_password=Change User Password +change_password_description=Use this view to change an existing user password. +change_password_instructions=Enter the new password for this user. +show_all=Show All + +# Check-in messages +check_in=Check In +checkin_options=Check In options +checkin_changes_info=Check in changes and keep file checked out +workingcopy_location=Working copy location +which_copy_checkin=Which copy do you want to check in? +which_copy_current=Use copy in current space +which_copy_other=Use copy uploaded from my computer +locate_doc_upload=Locate document to upload +file_location=Location +minor_change=Minor Change +major_change=Major Change +notes=Notes + +# Check-out messages +check_out=Check Out +copy_work_with=A copy of the file ''{0}'' will be made for you to work with. +copy_checkin_changes=When you have completed your changes you need to check in the file to allow others to view the changes. +copy_store_prompt=Where do you want to keep the copy of this file? +store_space_current=In the current space +store_space_selected=In the space selected +check_out_of=Check Out of +copy_file_checkedout=A copy of the file ''{0}'' is now checked out to you for editing. +edit_workingcopy_title=Edit the working copy now +edit_workingcopy_info=To edit the working copy of the file, click the link below and if asked select Save. +continue_working_title=Continue working +continue_working_info1=If you do not want to edit the file now click OK to close the page. +continue_working_info2=To edit the file in the future click the Edit action +download_complete=When the download is complete, click OK. +undo_checkout_for=Undo Check Out for +undo_checkout=Undo Check Out +undo_checkout_info=If you undo the check out of a document, the associated working copy will be deleted and all changes to it since the Check Out will be lost. + +# Document and Space details messages +details_of=Details of +preview_of=Preview of +modify_props_of=Modify Properties of +modify_space_properties=Modify Space Properties +modify_content_properties=Modify Content Properties +view_content_properties=View Content Properties +preview=Preview in Template +custom_view=Custom View +view_links=Links +not_inline_editable=This document is not inline editable. +allow_inline_editing=Allow Inline Editing +not_in_workflow=This document is not part of any workflow. +not_in_category=This document is not categorized. +not_in_category_space=This space is not categorized. +not_versioned=This document has no version history. +allow_categorization=Allow Categorization +allow_versioning=Allow Versioning +version_history=Version History +version=Version +document_properties=Document Properties +link_properties=Link Properties +general_properties=General Properties +other_properties=Other Properties +link_destination=Link Destination +link_destination_details=Link Destination Details +no_other_properties=This document does not have any other properties to show. +modify_categories_of=Modify categories of +space_props=Space Properties +choose_space_icon=Choose space icon +create_space_finish=To create your space click Create Space. +select_category=Select a category +selected_categories=Selected categories +no_selected_categories=No categories selected. +success_ownership=Successfully took ownership of the object. +success_unlock=Successfully unlocked the document. +inherit_permissions=Inherit Parent Space Permissions +success_inherit_permissions=Successfully changed Inherit Parent Permissions to 'Yes' +success_not_inherit_permissions=Successfully changed Inherit Parent Permissions to 'No' +apply_template=Apply Template +apply_dashboard_info=Select a template to be applied to the Space as a Custom view. +apply_dashboard_doc_info=Select a template to be applied to the Document as a Custom view. +apply_rss_feed=Apply RSS Feed Template +apply_rss_feed_info=Select a template to be applied to the Space as an RSS feed. +apply_rss_feed_warning1=This Space must be visible to the Guest user for the RSS feed to be publically viewable, you can Invite the Guest user using the +apply_rss_feed_warning2=view. +rss_feed=RSS Feed +rss_feed_link=RSS Feed Link + +# Export messages +export_info=Exports metadata and content from this or all Spaces. +export_from=Export From +package_name=Package Name +all_spaces_root=Complete Repository +current_space=Current Space +include_children=Include Children +include_self=Include this Space +run_export_in_background=Run export in background +export_error_info=If this option is selected the export will be performed in the background so the results may not appear immediately. You may also want to monitor the server console and log files for errors. + +# Import messages +import_info=Imports an Alfresco content package file into the repository. +import_package_description=Alfresco content package +run_import_in_background=Run import in background +import_error_info=If this option is selected the import will be performed in the background so the results may not appear immediately. You may also want to monitor the server console and log files for errors. + +# Edit Content messages +edit_file_title=Edit file +edit_file_prompt=To edit the file ''{0}'', click the link below and if asked select Save. +edit_download_complete=When the download is complete, click Close. +checkout_file_title=Check out file +checkout_you_may_want=You may want to check out this file to lock it and prevent other users from editing it. +checkout_hint1=Hint: When you check out a file a copy is made for you to work with. +checkout_hint2=When you have finished editing the copy you need to check it in to release the lock and allow others to work with the modified document. +checkout_want_to=to prevent the possibility of other users overwriting your changes. +checkout_warn=Note: You will lose any changes already made to this document. +local_copy_location=Local copy location +locate_content_upload=Locate and upload your document to the repository. + +# System Information and admin page messages +system_info=System Information +current_user=Current User +http_app_state=HTTP Application State +http_session_state=HTTP Session State +http_request_state=HTTP Request State +http_request_params=HTTP Request Parameters +http_request_headers=HTTP Request Headers +repository_props=Repository Properties +repository_patch_succeeded=Succeeded +repository_patch_failed=FAILED +system_props=System Properties +hide_details=Hide Details +show_details=Show Details +user_search_info=To find a user search for them using their first name, last name and/or user name. Alternatively to see all users click 'Show All', however, this may take some time if there are a lot of users in the system. +user_change_homespace_info=Selecting a new home space for a user will not remove the existing permissions on the original home space. You may wish to use the Manage Space Users dialog to modify permissions if they are no longer required on the original home space. + +# Content Wizard messages +add_content_dialog_title=Add Content Dialog +add_content_dialog_desc=This dialog helps you to add content to a space. +upload_content=Upload Content +properties=Properties +general=General +file_name=File Name +content_type=Content Type +content_format=Content Format +inline_editable=Inline Editable +locate_content=Locate content to upload +content_location=Location +uploaded_content=Uploaded Content +click_upload=Click upload +file_upload_success=''{0}'' was uploaded successfully. +modify_props_when_page_closes=Modify all properties when this page closes. +modify_props_when_wizard_closes=Modify all properties when this wizard closes. +modify_props_help_text=Rules applied to this content may require you to enter additional information. +content_finish_instruction=To add the content to this space click Finish. To review or change your selections click Back. +create_content_title=Create Content Wizard +create_content_desc=This wizard helps you to create a new document in a space. +create_content_step1_title=Step One - Specify name and select type +create_content_step1_desc=Specify the name and select the type of content you wish to create. +create_content_step2_title=Step Two - Enter Content +create_content_step2_desc=Enter your document content into the repository. +enter_content=Enter Content +select_type=Select Type +content=Content +text_content=Plain Text Content +html_content=HTML Content +xml_content=XML Content +create_xml_content_type_title=Create XML Content Type Wizard +create_xml_content_type_desc=Create XML Content Type +create_xml_content_type_step1_title=Upload an XML Schema +create_xml_content_type_step1_desc=Upload an XML Schema +create_xml_content_type_step2_title=Edit the XML Schema +create_xml_content_type_step2_desc=This is the generated XForm based on the schema provided. +edit_xml_schema=Edit XML Schema +template_type=Template Type +configure_presentation_templates=Configure Presentation Templates + +# Rule and Action Wizard messages +run_action_title=Run Action Wizard +run_action_desc=This wizard helps you run an action +run_action_step1_title=Step One - Select Actions +run_action_finish_instruction=To execute the action click Finish. To review or change your selections click Back. +create_rule_title=Create Rule Wizard +create_rule_desc=This wizard helps you create a new rule. +create_rule_step1_title=Step One - Select Conditions +create_rule_step2_title=Step Two - Select Actions +create_rule_step3_title=Step Three - Enter Details +create_rule_finish_instruction=To create the rule click Finish. To review or change your selections click Back. +edit_rule_title=Edit Rule Wizard +edit_rule_desc=This wizard helps you modify a rule. +edit_rule_finish_instruction=To update the rule click Finish. To review or change your selections click Back. +select_action=Select Action +select_an_action=Select an action... +select_a_type=Select a type... +action=Action +action_settings=Action Settings +set_action_values=Set action values +select_feature=Select required feature +version_notes=Version Notes +checkout_location=Check out location +destination=Destination +message=Message +category=Category +categories=Categories +change_category=Change Category +approve_flow=Approve Flow +approve_step_name=Name for approve step +move_or_copy=Choose whether you want to move or copy the content and also the location. +reject_flow=Reject Flow +want_reject_step=Do you want to provide a reject step? +reject_step_name=Name for reject step +required_format=Required format +details=Details +select_condition=Select Condition +select_a_condition=Select a condition... +condition=Condition +conditions=Conditions +condition_settings=Condition Settings +set_condition_values=Set condition values +select_checkout_prompt=Click here to select the check out location +condition_contains_desc=Enter the text pattern required, including any wildcards. The file name includes the file type extension when matching. +file_name_pattern=File name pattern +condition_contains_hints=Hints +condition_contains_hints_desc=Use zz* to match any name that begins with zz; use *.txt to match any text file; use *zz* to match any file name that contains zz anywhere including the beginning or end. +apply_to_sub_spaces=Apply rule to sub spaces +run_in_background=Run rule in background +rule_disabled=Disable rule +not=Not +click_set_and_add=Click to set values and add to list +click_add_to_list=Click to add to list +set_and_add_button=Set Values and Add +selected_conditions=Selected Rule Conditions +selected_actions=Selected Rule Actions +condition_has_aspect=Item has aspect ''{0}'' +condition_has_aspect_not=Item does not have aspect ''{0}'' +condition_is_subtype=Item is a subtype of ''{0}'' +condition_is_subtype_not=Item is not a subtype of ''{0}'' +condition_compare_mime_type=Item has a mimetype of ''{0}'' +condition_compare_mime_type_not=Item does not have a mimetype of ''{0}'' +condition_in_category=Item is in category ''{0}'' +condition_in_category_not=Item is not in category ''{0}'' +condition_compare_property_value=Name property matches ''{0}'' +condition_compare_property_value_not=Name property does not match ''{0}'' +action_add_features=Add aspect ''{0}'' +action_remove_features=Remove aspect ''{0}'' +action_specialise_type=Item is specialised to type ''{0}'' +action_simple_workflow={0} item to ''{1}'' if ''{2}'' action is taken. +action_link_category=Link to category ''{0}'' +action_transform=Copies content to ''{0}'' and transforms to ''{1}'' +action_transform_image=Copies image to ''{0}'' and transforms to ''{1}'' using option ''{2}'' +action_copy=Copy to ''{0}'' +action_move=Move to ''{0}'' +action_mail=Send email to ''{0}'' +action_mail_template=Use Template +action_check_in=Check in content as ''{0}'' with comment ''{1}'' +action_check_out=Check out content to ''{0}'' +action_set_property_value=Sets property ''{0}'' +action_import=Imports to ''{0}'' +action_script=Executes script ''{0}'' +action_script_select=Select a script to execute +not_condition_result=Check the item does not match the criteria above +space=Space +import_to=Import To +encoding=Encoding +encoding_utf8=UTF-8 +rule_type=Rule Type +rule_background_info=If this option is selected the rule will execute in the background so the results may not appear immediately. +select_recipients=Search for email recipients by Name or Group +selected_recipients=Selected email recipients +message_recipients=Message Recipients +email_message=Email message +insert_template=Insert Template +discard_template=Discard Template + +# Create Space Wizard messages +create_space_title=Create Space Wizard +create_space_desc=This wizard helps you to create a new space. +create_space_step1_title=Step One - Starting Space +create_space_step1_desc=Choose how you want to create your space. +create_space_step2_title=Step Two - Space Options +create_space_step2_desc=Select space options. +create_space_step3_title=Step Three - Space Details +create_space_step3_desc=Enter information about the space. +create_space_finish_instruction=To close this wizard and create your space click Finish. To review or change your selections click Back. +scratch=Scratch +an_existing_space=An existing space +a_template=A template +creating_from=Creating From +save_as_template=Save As Template +template_name=Template Name +select_a_template=Select a template... +select_a_script=Select a script... +starting_space=Starting Space +space_options=Space Options +space_details=Space Details +how_to_create_space=How do you want to create your space? +from_scratch=From scratch +based_on_existing_space=Based on an existing space +using_a_template=Using a template +existing_space=Existing Space +copy_existing_space=Copy existing space +structure=Structure +structure_contents=Structure and contents +space_copy_note=Note: Any content rules for spaces will also be copied. +space_type=Space Type +space_type_create=Select the type of space you want to create. +container=Folder Space +container_desc=A place for keeping and organizing documents and other spaces. +forums_desc=A place to discuss content with other users. +space_type_note=Note: If you can only see one type of space then other space types may not be enabled. See your System Administrator for further help. +template_space=Template Space +select_template=Select the template you want to use. + +# Create Website Wizard messages +create_website=Create Website +create_website_title=Create Website Wizard +create_website_desc=This wizard helps you create a new website space. +website_details=Website Details +create_website_step1_title=Step One - Website Details +create_website_step1_desc=Enter the information about the website. +create_website_finish_instruction=To close this wizard and create your website space click Finish. To review or change your selections click Back. + +# Browse Website and Sandboxes messages +title_browse_website=Browse Website Sandboxes +website_info=Use this view to browse the staging area and user sandboxes for a website. +staging_sandbox=Staging Sandbox + +# New User Wizard messages +new_user_title=New User Wizard +new_user_title_edit=Edit User Wizard +new_user_desc=This wizard helps you to add a user to the repository. +new_user_desc_edit=This wizard helps you modify a user in the repository. +new_user_step1_title=Step One - Person Properties +new_user_step1_desc=Enter information about this person. +new_user_step2_title=Step Two - User Properties +new_user_step2_desc=Enter information about this user. +new_user_finish_instruction=To add the user to this space click Finish. To review or change your selections click Back. +person_properties=Person Properties +user_properties=User Properties +first_name=First Name +last_name=Last Name +email=Email +company_id=Company ID +home_space_location=Home Space Location +home_space_name=Home Space Name + +# Trashcan messages +title_deleted_items=Deleted Items +title_delete_all=Delete All Items +title_recover_all=Recover All Items +title_recover_listed=Recover Listed Items +title_delete_listed=Delete Listed Items +title_delete_item=Delete Item +title_recover_item=Recover Item +title_recovery_report=Recovery Report +deleted_items=Deleted Items +manage_deleted_items=Manage Deleted Items +manage_deleted_items_description=Remove or recover previously deleted items +recover_all_items=Recover All Items +delete_all_items=Delete All Items +deleted_items_info=Use the Search to find deleted items by name or content and use the filters to reduce the list. +original_location=Original Location +deleted_date=Date Deleted +deleted_user=Deleted by User +recover=Recover +clear_search_results=Clear Search Results +search_deleted_items_name=Search by Name +search_deleted_items_text=Search by Content +deleted_items_for=for ''{0}'' +delete_item=Delete Item +delete_item_info=Permanently delete an item from the deleted file store +delete_item_confirm=Are you sure you want to permanently delete \"{0}\" from the deleted file store? The item cannot be recovered once this action has been performed. +recover_item=Recover Item +recover_item_info=Recover an item from the deleted file store +recover_item_confirm=Are you sure you want to recover \"{0}\" from the deleted file store? +delete_all_items_info=Permanently delete all files and spaces from the deleted file store +delete_all_items_confirm=Are you sure you want to permanently delete all files and spaces from the deleted file store? The items cannot be recovered once this action has been performed. +recover_all_items_info=Recover all files and spaces from the deleted file store +recover_all_items_confirm=Are you sure you want to recover all the deleted files and spaces from the deleted file store? +delete_listed_items=Delete Listed Items +delete_listed_items_info=Permanently delete the listed files and spaces from the deleted file store +delete_listed_items_confirm=Are you sure you want to permanently delete the following deleted files and spaces from the deleted file store? The items cannot be recovered once this action has been performed. +recover_listed_items=Recover Listed Items +recover_listed_items_info=Recover the listed files and spaces from the deleted file store +recover_listed_items_confirm=Are you sure you want to recover the following deleted files and spaces from the deleted file store? +recovered_item_success=The item \"{0}\" has been successfully recovered. +recovered_item_parent=Failed to recover the item \"{0}\" as the parent folder is missing, please select a new folder destination. +recovered_item_parent_short=Parent folder missing +recovered_item_permission=Failed to recover the item \"{0}\" as you do not have the appropriate permissions to restore the item to the parent folder, please select a new folder destination. +recovered_item_permission_short=No permissions to write +recovered_item_integrity=Failed to recover the item \"{0}\" as there is now an item in the parent folder with the same name, please select a new folder destination. +recovered_item_integrity_short=Item with same name exists +recovered_item_failure=Failed to recover the item \"{0}\" due to error: {1} +recovered_item_failure_short=Failed +delete_item_success=The item \"{0}\" has been permanently deleted. +title_deleted_item_details=Deleted Item Details +deleteditem_details_description=Details of the deleted item +alternative_destination=You may select a destination where you wish the recovered items to be placed. If you do not select a destination, the original location of the item is used. Recovery of an item may fail if the destination does not exist or you do not have permission to add items there. +user_filter_who=Who +user_filter_all=All +user_filter_user=User +date_filter_when=When +date_filter_all=All +date_filter_today=Today +date_filter_week=Last 7 days +date_filter_month=Last 30 days +recovery_report=Recovered Items Report +recovery_report_info=The results of recovering the selected items +recovery_report_success=The following items were recovered successfully +recovery_report_failed=The following items failed to recover +recovery_report_reason=Failure Reason + +# My Alfresco messages +my_alfresco=My Alfresco +title_my_alfresco=My Alfresco +dashboard_info=My Alfresco Dashboard +dashboard_description=Configure this view and build your personal Alfresco dashboard +configure=Configure +error_dashboard=An error occurred in one of the dashlets. + +# My Alfresco Layout Manager wizard messages +configure_dashboard_title=Configure Dashboard Wizard +configure_dashboard_desc=This wizard helps you configure your dashboard layout and contents +step_layout=Layout +configure_dashboard_step1_title=Step One - Select Layout +configure_dashboard_step1_desc=Choose the layout and number of columns for your dashboard. +step_columns=Components +configure_dashboard_step2_title=Step Two - Select Components +configure_dashboard_step2_desc=Select the components for your dashboard and add them to the columns. +configure_dashboard_finish_instruction=To save the dashboard configuration click Finish. To review or change your selections click Back. +select_layout=Select the style of layout for your dashboard. Changing your existing dashboard layout to another with less columns will result in the additional columns being removed. +select_column=Select the column to configure +dashlet_list=Available Components +dashlet_btn_select=Add +dashlet_btn_remove=Remove +selected_dashlets=Selected Components +dashboard_column=Column +column_max_components=this column can display {0} components + +# My Alfresco Layouts messages +layout_single_label=Single Column +layout_single_desc=This layout displays components in a single column the full width of the page +layout_narrow_left_label=Two Column Narrow Left +layout_narrow_left_desc=This layout display components in two columns with a narrow left hand column +layout_narrow_right_label=Two Column Narrow Right +layout_narrow_right_desc=This layout display components in two columns with a narrow right hand column +layout_three_column_label=Three Column +layout_three_column_desc=This layout displays components across three columns of equal width + +# My Alfresco Dashlet components messages +dashlet_gettingstarted_label=Getting Started +dashlet_gettingstarted_desc=Displays helpful information for getting started with the Alfresco web-client +dashlet_mydocuments=My Documents +dashlet_mydocuments_desc=Displays a list of the documents in my home space +dashlet_checkedoutdocs=My Checked Out Documents +dashlet_checkedoutdocs_desc=Displays a list of the documents checked out to me +dashlet_myimages=My Images +dashlet_myimages_desc=Displays a 3 column thumbnail list of the images in my home space +gettingstarted_commontasks=Common Tasks +gettingstarted_browse=Browse items in your home space +gettingstarted_browse_desc=From the toolbar click My Home to display a list of items in the space. +gettingstarted_createspace=Create a space in your home space +gettingstarted_createspace_desc=Navigate to your home space. In the space info area, from the menu under Create, click Create Space and enter information about the space. +gettingstarted_addcontent=Add content to your home space +gettingstarted_addcontent_desc=Navigate to your home space. In the space info area, click Add Content and enter information about the content to be uploaded. +gettingstarted_createcontent=Create content in your home space +gettingstarted_createcontent_desc=Navigate to your home space. In the space info area, click Create Content under Create and enter information about the content to be created. +gettingstarted_demonstration=Demonstration +gettingstarted_demonstration_desc=Watch a demonstration of how Alfresco can be used to create a marketing launch. +gettingstarted_featuretour=Feature Tour +gettingstarted_featuretour_desc=Take a tour of some of the key features in Alfresco. +gettingstarted_onlinehelp=Online Help +gettingstarted_onlinehelp_desc=Click the help icon to display Alfresco Help topics. + +# User Console and Settings messages +title_user_console=User Options +title_edit_user_details=Edit User Details +user_console=User Options +user_console_info=User Options +user_console_description=Use this page to change your options and settings +my_details=My Details +general_pref=General Preferences +change_my_password_description=Use this view to change your password +change_my_password_instructions=Enter your new password. +old_password=Old Password +new_password=New Password +edit_user_details=Edit User Details +edit_user_details_description=Use this view to change your user details and email address +start_location=Start Location + +# Delete Space Dialog messages +select_delete_operation=What do you want to delete? +delete_op_all=This space and all its contents. Note: Rules will also be deleted. +delete_op_files=Only the files within this space. +delete_op_folders=Only the folders within this space. +delete_op_contents=Files and folders within this space. + +# Email users dialog +email_space_users=Email Space users +email_space_users_desc=Send an email to the users and groups assigned to this space. + +# Workflow messages +modify_workflow_props=Modify Properties of Simple Workflow +name_approve_step=Name for approve step +name_reject_step=Name for reject step +select_reject_step=Do you want to provide a reject step? +choose_copy_move_location=Choose whether you want to move or copy the content and also the location. +start_workflow=Start Workflow +start_workflow_wizard=Start New Workflow Wizard +start_workflow_desc=This wizard helps you start a workflow for an item in the repository. +available_workflows=Available workflows +step_choose_workflow=Choose Workflow +start_workflow_choose_title=Choose Workflow +start_workflow_choose_desc=Choose the workflow you want to start +step_workflow_options=Workflow Options +start_workflow_options_title=Workflow Options +start_workflow_options_desc=Select options for the workflow +start_workflow_finish_instruction=To start the workflow press Finish. To review or change your selections click Back. +start_workflow_no_metadata=There is no metadata to collect for this particular workflow. +start_workflow_no_workflows=There are no workflows currently deployed in the repository, press Cancel to exit the wizard. +users_and_roles=Users and their Roles +resources=Resources +manage_task=Manage Task +manage_task_title=Manage Task +manage_task_desc=This dialog allows the task to be managed. +view_completed_task_title=View Completed Task +view_completed_task_desc=This dialog allows the completed task details to be viewed. +task_properties=Task Properties +id=Id +status=Status +completed=Completed +source=Source +priority=Priority +my_tasks_todo_title=My Tasks To Do +my_tasks_todo_desc=List of your tasks still to complete +my_tasks_completed_title=My Completed Tasks +my_tasks_completed_desc=List of your completed tasks +due_date=Due Date +completed_on=Completed on +outcome=Outcome +reassign=Reassign +cancel_workflow=Cancel Workflow +cancel_workflow_info=To cancel this workflow, click OK. +cancel_workflow_confirm=Are you sure you want to cancel the \"{0}\" workflow? +error_cancel_workflow=Unable to cancel the workflow due to system error: +reassign_task_title=Reassign Task +reassign_task_desc=This dialog allows you to reassign a task. +reassign_select_user=Select the user to assign the task to, then press OK. +error_reassign_task=Unable to reassign the task due to system error: +part_of_workflow=Part of Workflow +initiated_by=Initiated by +start_date=Start date +add_resource=Add Resource +view_properties=View Content Properties +edit_properties=Edit Content Properties + +# Admin Console messages +title_admin_console=Administration Console +admin_console=Administration Console +admin_description=Use this view to perform system administration functions. +admin_limited_license=Licensed: {0} license granted to {1} and limited to {3} days expiring {4,date,short} ({5} days remaining - issued on {2,date,short}). +admin_unlimited_license=Licensed: {0} license granted to {1} and does not expire (issued on {2,date,short}). +admin_invalid_license=Licensed: LICENSE INVALID - Alfresco Repository restricted to read-only capability. + +# UI Page Titles +title_about=About Alfresco +title_login=Alfresco Web Client - Login +title_relogin=Alfresco Web Client - Logged Out +title_error=Alfresco Web Client - System Error +title_browse=Alfresco Web Client +title_inviteusers_invite=Invite Users - Invite +title_inviteusers_notify=Invite Users - Notify +title_invitecontentusers_invite=Invite Content Users - Invite +title_invitecontentusers_notify=Invite Content Users - Notify +title_change_user_roles=Change User Roles +title_remove_invited_user=Remove Invited User +title_advanced_search=Advanced Search +title_checkin_file=Check In File +title_checkout_file=Check Out File +title_checkout_file_link=Check Out File Download +title_delete_file=Delete File +title_delete_rule=Delete Rule +title_delete_user=Delete User +title_delete_space=Delete Space +title_file_details=Document Details +title_file_preview=Preview In Template +title_edit_categories=Edit Categories +title_edit_doc_props=Edit Document Properties +title_edit_link_props=Edit Link Properties +title_edit_file=Edit File +title_edit_html_inline=Edit HTML File Inline +title_edit_text_inline=Edit Text File Inline +title_edit_simple_workflow=Edit Simple Workflow +title_edit_space=Edit Space Details +title_rules=Space Rules +title_space_details=Space Details +title_apply_template=Apply Template +title_system_info=System Information +title_undo_checkout=Undo Check Out +title_update_file=Update File Content +title_users=User Management +title_invited_users=Manage Invited Users +title_content_users=Manage Content Users +title_add_content=Add Content +title_create_content=Create New Content +title_create_content_props=Create New Content - Properties +title_create_content_summary=Create New Content - Summary +title_action_add_feature=Add Feature Action +title_action_remove_feature=Remove Feature Action +title_action_checkin=Check In Action +title_action_checkout=Check Out Action +title_action_copy=Copy Action +title_action_move=Move Action +title_action_script=Script Action +title_action_import=Import Action +title_action_email=Email Action +title_action_link_category=Link Category Action +title_action_simple_workflow=Simple Workflow Action +title_action_transform=Transform Action +title_action_transform_image=Transform Image Action +title_action_specialise_type=Specialise Type Action +title_condition_contains_text=Contains Text Condition +title_condition_has_mimetype=Has Mimetype Condition +title_condition_in_category=In Category Condition +title_condition_is_subtype=Is Subtype Condition +title_condition_has_aspect=Has Aspect Condition +title_new_user_person_props=User - Person Properties +title_new_user_user_props=User - User Properties +title_new_user_summary=User - Summary +title_export=Export +title_import=Import +title_admin_store_browser=Alfresco Store Browser +title_admin_node_browser=Alfresco Node Browser +title_admin_search_results=Node Browser Search Results +title_forums=Forum Space +title_forum=Forum +title_topic=Topic +title_delete_forums_space=Delete Forum Space +title_delete_forum_space=Delete Forum +title_delete_topic_space=Delete Topic +title_delete_post=Delete Post +title_create_forums=Create Forum Space +title_create_forum=Create Forum +title_forums_details=Forum Space Details +title_forum_details=Forum Details +title_create_topic=Create Topic +title_create_discussion=Create Discussion +title_topic_details=Topic Details +title_create_post=Post Message +title_create_reply=Create Reply +title_edit_forums=Edit Forum Space Details +title_edit_forum=Edit Forum Details +title_edit_topic=Edit Topic Details +title_edit_post=Edit Post +title_noaccess=No Access + +# UI Error messages +error_generic=A system error happened during the operation: {0} +error_noderef=Unable to find the repository item referenced by Id: {0} - the record has probably been deleted from the database. +error_deleted_folder=The folder item referenced by Id: {0} - has been deleted from the database. The system has changed your folder location as the folder you were in no longer exists. +error_homespace=The Home Space node referenced by Id: {0} cannot be found. It may have been deleted from the database. Please contact your system administrator. +error_search=Search failed due to system error: {0} +error_exists=A Space or File with that name already exists: {0} +error_delete_space=Unable to delete Space due to system error: +error_delete_file=Unable to delete File due to system error: +error_checkout=Unable to check out Content Node due to system error: +error_update=Unable to update Content Node due to system error: +error_cancel_checkout=Unable to cancel check out of Content Node due to system error: +error_checkin=Unable to check in Content Node due to system error: +error_paste=Unable to paste item due to system error: +error_login_user=Unable to login - unknown username/password. +error_login_missing=Must specify username and password. +error_delete_rule=Unable to delete Rule due to system error: +error_actions=Failed to run Actions due to error: {0} +error_rule=Failed to create Rule due to error: {0} +error_space=Failed to create new space due to error: {0} +error_person=Failed to create Person due to error: {0} +error_delete_user=Failed to delete User due to error: {0} +error_delete_user_object=Unable to delete the User object associated with the Person. This is not an error if an external authentication mechanism such as NTLM was previously active. +error_remove_user=Failed to remove User due to error: {0} +error_password_match=Please ensure that both password fields contain the same value. +error_property=Property ''{0}'' is not available for this node +error_create_space_dialog=Please correct the errors below then click Create Space. +error_create_forums_dialog=Please correct the errors below then click Create Forum Space. +error_create_forum_dialog=Please correct the errors below then click Create Forum. +error_create_topic_dialog=Please correct the errors below then click Create Topic. +error_create_post_dialog=Please correct the errors below then click Post. +error_create_reply_dialog=Please correct the errors below then click Reply. +error_create_category_dialog=Please correct the errors below then click New Category. +error_create_group_dialog=Please correct the errors below then click Create Group. +error_dialog=Please correct the errors below then click OK. +error_wizard=Please correct the errors below then click Finish. +error_update_category=Failed to update category due to system error: {0} +error_update_simpleworkflow=Failed to update simple workflow due to system error: {0} +error_workflow_approve=Failed to approve the document due to system error: {0} +error_workflow_reject=Failed to reject the document due to system error: {0} +error_aspect_classify=Failed to apply the ''classifiable'' aspect to the document due to system error: {0} +error_aspect_classify_space=Failed to apply the ''classifiable'' aspect to the space due to system error: {0} +error_aspect_versioning=Failed to apply the ''versionable'' aspect to the document due to system error: {0} +error_aspect_inlineeditable=Failed to apply the ''inlineeditable'' aspect to the document due to system error: {0} +error_content_missing=The node''s content is missing: \n node: {0} \n reader: {1} \nPlease contact your system administrator. +error_export=Failed to execute export: {0} +error_import=Failed to execute import: {0} +error_import_no_file=Can not find an ACP file to import! +error_import_empty_file=You can not import an empty ACP file! +error_import_all=Please correct the import errors below then click OK. +error_export_all=Please correct the export errors below then click OK. +error_save_search=Failed to save search due to error: {0} +error_restore_search=Failed to restore saved search due to error: {0} +error_shortcut_permissions=Unable to navigate to the item as it cannot be read by this user. Another user may have modified the permission. + +# Confirmations +return_to_application=Return to application +delete_space_info=To remove this space and all of its contents, click OK. +delete_space_confirm=Are you sure you want to delete \"{0}\" and all its contents? +delete_forums_info=To remove this forum space and its contents, click OK. +delete_forum_info=To remove this forum and its topics, click OK. +delete_forum_confirm=Are you sure you want to delete \"{0}\" and all its topics? +delete_topic_info=To remove this topic and its posts, click OK. +delete_topic_confirm=Are you sure you want to delete \"{0}\" and all its posts? +delete_post_info=To remove this post from the topic, click OK. +delete_post_confirm=Are you sure you want to delete the post from \"{0}\"? +delete_file_info=To remove this file and any previous versions, click OK. +delete_file_confirm=Are you sure you want to delete \"{0}\" and all previous versions? +delete_rule_info=To remove this rule from the space, click Yes. +delete_user_info=To delete this user from the system, click Yes. +delete_rule_confirm=Are you sure you want to delete \"{0}\"? +delete_user_confirm=The User will no longer be able to access the system. Are you sure you want to delete user \"{0}\"? +remove_invited_user_confirm=The User will no longer be able to access the documents and folders in this space. Are you sure you want to remove user \"{0}\"? +remove_content_user_confirm=The User will no longer be able to access this content. Are you sure you want to remove user \"{0}\"? +delete_companyroot_confirm=WARNING: This folder is a special folder accessed by all Users! Please be sure that you wish to delete this folder. It may cause System Errors if you remove it. + +# Status Messages +status_space_created=Successfully created space ''{0}''. +status_space_deleted=Successfully deleted space ''{0}''. +status_space_updated=Successfully updated space ''{0}''. + +# Validation Messages +validation_mandatory={0} is a mandatory field. +validation_string_length={0} must be between {1} and {2} characters in length. +validation_regex={0} is invalid. +validation_regex_not_match={0} is invalid. +validation_numeric_range={0} must be between {1} and {2}. validation_invalid_character=is an invalid character. \ No newline at end of file diff --git a/config/alfresco/web-client-config-properties.xml b/config/alfresco/web-client-config-properties.xml index c3176fbaff..20b4c73d4c 100644 --- a/config/alfresco/web-client-config-properties.xml +++ b/config/alfresco/web-client-config-properties.xml @@ -11,7 +11,7 @@ + ignore-if-missing="false" component-generator="TextAreaGenerator" /> + + + + + + + + + + + + + + + + + @@ -54,7 +78,7 @@ - + @@ -62,7 +86,7 @@ - + @@ -75,7 +99,7 @@ - + @@ -87,7 +111,7 @@ - + @@ -282,4 +306,274 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/config/alfresco/web-client-config-wizards.xml b/config/alfresco/web-client-config-wizards.xml index 5cb58cde31..e41292d177 100644 --- a/config/alfresco/web-client-config-wizards.xml +++ b/config/alfresco/web-client-config-wizards.xml @@ -265,6 +265,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/config/alfresco/web-client-config-workflow-actions.xml b/config/alfresco/web-client-config-workflow-actions.xml index 56516bb451..5f1fb1f61a 100644 --- a/config/alfresco/web-client-config-workflow-actions.xml +++ b/config/alfresco/web-client-config-workflow-actions.xml @@ -5,6 +5,7 @@ start_workflow /images/icons/new_workflow.gif + org.alfresco.web.action.evaluator.StartWorkflowEvaluator wizard:startWorkflow #{WizardManager.setupParameters} @@ -59,6 +60,9 @@ + + Write + edit_properties /images/icons/Change_details.gif dialog:editContentProperties diff --git a/config/alfresco/web-client-config.xml b/config/alfresco/web-client-config.xml index c15afbdb1d..37ed10eaf4 100644 --- a/config/alfresco/web-client-config.xml +++ b/config/alfresco/web-client-config.xml @@ -162,6 +162,13 @@ + + + + + + + @@ -190,6 +197,11 @@ + + + @@ -199,10 +211,6 @@ - - false @@ -255,6 +263,13 @@ + + + + + + + @@ -265,7 +280,7 @@ - + @@ -288,7 +303,7 @@ - + @@ -306,7 +321,7 @@ - + @@ -316,10 +331,10 @@ - + - + @@ -341,13 +356,13 @@ - + - + @@ -355,5 +370,5 @@ - + diff --git a/source/java/org/alfresco/web/action/evaluator/StartWorkflowEvaluator.java b/source/java/org/alfresco/web/action/evaluator/StartWorkflowEvaluator.java new file mode 100644 index 0000000000..0d0de2e2d7 --- /dev/null +++ b/source/java/org/alfresco/web/action/evaluator/StartWorkflowEvaluator.java @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2005 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ +package org.alfresco.web.action.evaluator; + +import javax.faces.context.FacesContext; + +import org.alfresco.web.action.ActionEvaluator; +import org.alfresco.web.app.servlet.FacesHelper; +import org.alfresco.web.bean.NavigationBean; +import org.alfresco.web.bean.repository.Node; + +/** + * UI Action Evaluator - Start workflow on a node. + * + * @author gavinc + */ +public class StartWorkflowEvaluator implements ActionEvaluator +{ + /** + * @see org.alfresco.web.action.ActionEvaluator#evaluate(org.alfresco.web.bean.repository.Node) + */ + public boolean evaluate(Node node) + { + NavigationBean nav = + (NavigationBean)FacesHelper.getManagedBean(FacesContext.getCurrentInstance(), "NavigationBean"); + return (nav.getIsGuest() == false); + } +} diff --git a/source/java/org/alfresco/web/app/Application.java b/source/java/org/alfresco/web/app/Application.java index c4132a36ab..c10a75e421 100644 --- a/source/java/org/alfresco/web/app/Application.java +++ b/source/java/org/alfresco/web/app/Application.java @@ -1,925 +1,925 @@ -/* - * Copyright (C) 2005 Alfresco, Inc. - * - * Licensed under the Mozilla Public License version 1.1 - * with a permitted attribution clause. You may obtain a - * copy of the License at - * - * http://www.alfresco.org/legal/license.txt - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, - * either express or implied. See the License for the specific - * language governing permissions and limitations under the - * License. - */ -package org.alfresco.web.app; - -import java.io.IOException; -import java.util.Locale; -import java.util.Map; -import java.util.Properties; -import java.util.ResourceBundle; -import java.util.StringTokenizer; - -import javax.faces.context.FacesContext; -import javax.portlet.PortletContext; -import javax.portlet.PortletSession; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; - -import org.alfresco.config.ConfigService; -import org.alfresco.repo.importer.ImporterBootstrap; -import org.alfresco.service.cmr.repository.StoreRef; -import org.alfresco.web.app.servlet.AuthenticationHelper; -import org.alfresco.web.app.servlet.FacesHelper; -import org.alfresco.web.bean.ErrorBean; -import org.alfresco.web.bean.dashboard.DashboardManager; -import org.alfresco.web.bean.dialog.DialogManager; -import org.alfresco.web.bean.repository.User; -import org.alfresco.web.bean.wizard.WizardManager; -import org.alfresco.web.config.ClientConfigElement; -import org.apache.commons.logging.Log; -import org.springframework.web.context.WebApplicationContext; -import org.springframework.web.context.support.WebApplicationContextUtils; -import org.springframework.web.jsf.FacesContextUtils; - -/** - * Utilities class - * - * @author gavinc - */ -public class Application -{ - private static final String LOCALE = "locale"; - - public static final String BEAN_CONFIG_SERVICE = "webClientConfigService"; - public static final String BEAN_DATA_DICTIONARY = "dataDictionary"; - public static final String BEAN_IMPORTER_BOOTSTRAP = "spacesBootstrap"; - - public static final String MESSAGE_BUNDLE = "alfresco.messages.webclient"; - - private static ThreadLocal inPortalServer = new ThreadLocal(); - private static StoreRef repoStoreRef; - private static String rootPath; - private static String companyRootId; - private static String glossaryFolderName; - private static String spaceTemplatesFolderName; - private static String contentTemplatesFolderName; - private static String emailTemplatesFolderName; - private static String rssTemplatesFolderName; - private static String savedSearchesFolderName; - private static String scriptsFolderName; - private static String guestHomeFolderName; - private static String websitesFolderName; - - /** - * Private constructor to prevent instantiation of this class - */ - private Application() - { - } - - /** - * Sets whether this application is running inside a portal server - * - * @param inPortal true to indicate the application is running as a portlet - */ - public static void setInPortalServer(boolean inPortal) - { - inPortalServer.set(inPortal); - } - - /** - * Determines whether the server is running in a portal - * - * @return true if we are running inside a portal server - */ - public static boolean inPortalServer() - { - return (inPortalServer.get() != null ? inPortalServer.get() : false); - } - - /** - * Handles errors thrown from servlets - * - * @param servletContext The servlet context - * @param request The HTTP request - * @param response The HTTP response - * @param error The exception - * @param logger The logger - */ - public static void handleServletError(ServletContext servletContext, HttpServletRequest request, - HttpServletResponse response, Throwable error, Log logger, String returnPage) - throws IOException, ServletException - { - // get the error bean from the session and set the error that occurred. - HttpSession session = request.getSession(); - ErrorBean errorBean = (ErrorBean)session.getAttribute(ErrorBean.ERROR_BEAN_NAME); - if (errorBean == null) - { - errorBean = new ErrorBean(); - session.setAttribute(ErrorBean.ERROR_BEAN_NAME, errorBean); - } - errorBean.setLastError(error); - errorBean.setReturnPage(returnPage); - - // try and find the configured error page - boolean errorShown = false; - String errorPage = getErrorPage(servletContext); - - if (errorPage != null) - { - if (logger.isDebugEnabled()) - logger.debug("An error has occurred, redirecting to error page: " + errorPage); - - if (response.isCommitted() == false) - { - errorShown = true; - response.sendRedirect(request.getContextPath() + errorPage); - } - else - { - if (logger.isDebugEnabled()) - logger.debug("Response is already committed, re-throwing error"); - } - } - else - { - if (logger.isDebugEnabled()) - logger.debug("No error page defined, re-throwing error"); - } - - // if we could not show the error page for whatever reason, re-throw the error - if (!errorShown) - { - if (error instanceof IOException) - { - throw (IOException)error; - } - else if (error instanceof ServletException) - { - throw (ServletException)error; - } - else - { - throw new ServletException(error); - } - } - } - - /** - * Retrieves the DialogManager managed bean - * - * @return DialogManager bean - */ - public static DialogManager getDialogManager() - { - return (DialogManager)FacesHelper.getManagedBean(FacesContext.getCurrentInstance(), "DialogManager"); - } - - /** - * Retrieves the WizardManager managed bean - * - * @return WizardManager bean - */ - public static WizardManager getWizardManager() - { - return (WizardManager)FacesHelper.getManagedBean(FacesContext.getCurrentInstance(), "WizardManager"); - } - - /** - * Retrieves the DashboardManager managed bean - * - * @return DashboardManager bean - */ - public static DashboardManager getDashboardManager() - { - return (DashboardManager)FacesHelper.getManagedBean(FacesContext.getCurrentInstance(), "DashboardManager"); - } - - /** - * Retrieves the configured error page for the application - * - * @param servletContext The servlet context - * @return The configured error page or null if the configuration is missing - */ - public static String getErrorPage(ServletContext servletContext) - { - return getErrorPage(WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext)); - } - - /** - * Retrieves the configured error page for the application - * - * @param portletContext The portlet context - * @return - */ - public static String getErrorPage(PortletContext portletContext) - { - return getErrorPage((WebApplicationContext)portletContext.getAttribute( - WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE)); - } - - /** - * Retrieves the configured login page for the application - * - * @param servletContext The servlet context - * @return The configured login page or null if the configuration is missing - */ - public static String getLoginPage(ServletContext servletContext) - { - return getLoginPage(WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext)); - } - - /** - * Retrieves the configured login page for the application - * - * @param portletContext The portlet context - * @return - */ - public static String getLoginPage(PortletContext portletContext) - { - return getLoginPage((WebApplicationContext)portletContext.getAttribute( - WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE)); - } - - /** - * @return Returns the User object representing the currently logged in user - */ - public static User getCurrentUser(HttpSession session) - { - return (User)session.getAttribute(AuthenticationHelper.AUTHENTICATION_USER); - } - - /** - * @return Returns the User object representing the currently logged in user - */ - public static User getCurrentUser(FacesContext context) - { - return (User)context.getExternalContext().getSessionMap().get(AuthenticationHelper.AUTHENTICATION_USER); - } - - /** - * @return Returns the repository store URL (retrieved from config service) - */ - public static StoreRef getRepositoryStoreRef(ServletContext context) - { - return getRepositoryStoreRef(WebApplicationContextUtils.getRequiredWebApplicationContext(context)); - } - - /** - * @return Returns the repository store URL (retrieved from config service) - */ - public static StoreRef getRepositoryStoreRef(FacesContext context) - { - return getRepositoryStoreRef(FacesContextUtils.getRequiredWebApplicationContext(context)); - } - - /** - * @return Returns id of the company root - */ - public static String getCompanyRootId() - { - return companyRootId; - } - - /** - * Sets the company root id. This is setup by the ContextListener. - * - * @param id The company root id - */ - public static void setCompanyRootId(String id) - { - companyRootId = id; - } - - /** - * @return Returns the root path for the application - */ - public static String getRootPath(ServletContext context) - { - return getRootPath(WebApplicationContextUtils.getRequiredWebApplicationContext(context)); - } - - /** - * @return Returns the root path for the application - */ - public static String getRootPath(FacesContext context) - { - return getRootPath(FacesContextUtils.getRequiredWebApplicationContext(context)); - } - - /** - * @return Returns the glossary folder name - */ - public static String getGlossaryFolderName(ServletContext context) - { - return getGlossaryFolderName(WebApplicationContextUtils.getRequiredWebApplicationContext(context)); - } - - /** - * @return Returns the glossary folder name - */ - public static String getGlossaryFolderName(FacesContext context) - { - return getGlossaryFolderName(FacesContextUtils.getRequiredWebApplicationContext(context)); - } - - /** - * @return Returns the Space templates folder name - */ - public static String getSpaceTemplatesFolderName(ServletContext context) - { - return getSpaceTemplatesFolderName(WebApplicationContextUtils.getRequiredWebApplicationContext(context)); - } - - /** - * @return Returns the Space templates folder name - */ - public static String getSpaceTemplatesFolderName(FacesContext context) - { - return getSpaceTemplatesFolderName(FacesContextUtils.getRequiredWebApplicationContext(context)); - } - - /** - * @return Returns the Content templates folder name - */ - public static String getContentTemplatesFolderName(ServletContext context) - { - return getContentTemplatesFolderName(WebApplicationContextUtils.getRequiredWebApplicationContext(context)); - } - - /** - * @return Returns the Content templates folder name - */ - public static String getContentTemplatesFolderName(FacesContext context) - { - return getContentTemplatesFolderName(FacesContextUtils.getRequiredWebApplicationContext(context)); - } - - /** - * @return Returns the Email templates folder name - */ - public static String getEmailTemplatesFolderName(ServletContext context) - { - return getEmailTemplatesFolderName(WebApplicationContextUtils.getRequiredWebApplicationContext(context)); - } - - /** - * @return Returns the Email templates folder name - */ - public static String getEmailTemplatesFolderName(FacesContext context) - { - return getEmailTemplatesFolderName(FacesContextUtils.getRequiredWebApplicationContext(context)); - } - - /** - * @return Returns the RSS templates folder name - */ - public static String getRSSTemplatesFolderName(ServletContext context) - { - return getRSSTemplatesFolderName(WebApplicationContextUtils.getRequiredWebApplicationContext(context)); - } - - /** - * @return Returns the RSS templates folder name - */ - public static String getRSSTemplatesFolderName(FacesContext context) - { - return getRSSTemplatesFolderName(FacesContextUtils.getRequiredWebApplicationContext(context)); - } - - /** - * @return Return the Saved Searches folder name - */ - public static String getSavedSearchesFolderName(ServletContext context) - { - return getSavedSearchesFolderName(WebApplicationContextUtils.getRequiredWebApplicationContext(context)); - } - - /** - * @return Return the Saved Searches folder name - */ - public static String getSavedSearchesFolderName(FacesContext context) - { - return getSavedSearchesFolderName(FacesContextUtils.getRequiredWebApplicationContext(context)); - } - - /** - * @return Return the JavaScript scripts folder name - */ - public static String getScriptsFolderName(ServletContext context) - { - return getScriptsFolderName(WebApplicationContextUtils.getRequiredWebApplicationContext(context)); - } - - /** - * @return Return the JavaScript scripts folder name - */ - public static String getScriptsFolderName(FacesContext context) - { - return getScriptsFolderName(FacesContextUtils.getRequiredWebApplicationContext(context)); - } - - /** - * @return Return the Guest Home folder name - */ - public static String getGuestHomeFolderName(ServletContext context) - { - return getGuestHomeFolderName(WebApplicationContextUtils.getRequiredWebApplicationContext(context)); - } - - /** - * @return Return the Guest Home folder name - */ - public static String getGuestHomeFolderName(FacesContext context) - { - return getGuestHomeFolderName(FacesContextUtils.getRequiredWebApplicationContext(context)); - } - - /** - * @return the Websites folder name - */ - public static String getWebsitesFolderName(ServletContext context) - { - return getWebsitesFolderName(WebApplicationContextUtils.getRequiredWebApplicationContext(context)); - } - - /** - * @return the Websites folder name - */ - public static String getWebsitesFolderName(FacesContext context) - { - return getWebsitesFolderName(FacesContextUtils.getRequiredWebApplicationContext(context)); - } - - /** - * Set the language locale for the current user context - * - * @param context FacesContext for current user - * @param code The ISO locale code to set - */ - public static void setLanguage(FacesContext context, String code) - { - Locale locale = parseLocale(code); - - // set locale for JSF framework usage - context.getViewRoot().setLocale(locale); - - // set locale for our framework usage - context.getExternalContext().getSessionMap().put(LOCALE, locale); - - // clear the current message bundle - so it's reloaded with new locale - context.getExternalContext().getSessionMap().remove(MESSAGE_BUNDLE); - } - - /** - * Set the language locale for the current user session - * - * @param session HttpSession for current user - * @param code The ISO locale code to set - */ - public static void setLanguage(HttpSession session, String code) - { - Locale locale = parseLocale(code); - - session.setAttribute(LOCALE, locale); - session.removeAttribute(MESSAGE_BUNDLE); - } - - /** - * @param code Locale code (java format with underscores) to parse - * @return Locale object or default if unable to parse - */ - private static Locale parseLocale(String code) - { - Locale locale = Locale.getDefault(); - - StringTokenizer t = new StringTokenizer(code, "_"); - int tokens = t.countTokens(); - if (tokens == 1) - { - locale = new Locale(code); - } - else if (tokens == 2) - { - locale = new Locale(t.nextToken(), t.nextToken()); - } - else if (tokens == 3) - { - locale = new Locale(t.nextToken(), t.nextToken(), t.nextToken()); - } - - return locale; - } - - /** - * Return the language Locale for the current user context - * - * @param context FacesContext for the current user - * - * @return Current language Locale set or the VM default if none set - */ - public static Locale getLanguage(FacesContext context) - { - Locale locale = (Locale)context.getExternalContext().getSessionMap().get(LOCALE); - return locale != null ? locale : Locale.getDefault(); - } - - /** - * Return the language Locale for the current user Session. - * - * @param session HttpSession for the current user - * - * @return Current language Locale set or the VM default if none set - */ - public static Locale getLanguage(HttpSession session) - { - Locale locale = (Locale)session.getAttribute(LOCALE); - return locale != null ? locale : Locale.getDefault(); - } - - /** - * Return the language Locale for the current user PortletSession. - * - * @param session PortletSession for the current user - * - * @return Current language Locale set or the VM default if none set - */ - public static Locale getLanguage(PortletSession session) - { - Locale locale = (Locale)session.getAttribute(LOCALE); - return locale != null ? locale : Locale.getDefault(); - } - - /** - * Get the specified I18N message string from the default message bundle for this user - * - * @param context FacesContext - * @param msg Message ID - * - * @return String from message bundle or $$msg$$ if not found - */ - public static String getMessage(FacesContext context, String msg) - { - return getBundle(context).getString(msg); - } - - /** - * Get the specified I18N message string from the default message bundle for this user - * - * @param session HttpSession - * @param msg Message ID - * - * @return String from message bundle or $$msg$$ if not found - */ - public static String getMessage(HttpSession session, String msg) - { - return getBundle(session).getString(msg); - } - - /** - * Get the specified the default message bundle for this user - * - * @param session HttpSession - * - * @return ResourceBundle for this user - */ - public static ResourceBundle getBundle(HttpSession session) - { - ResourceBundle bundle = (ResourceBundle)session.getAttribute(MESSAGE_BUNDLE); - if (bundle == null) - { - // get Locale from language selected by each user on login - Locale locale = (Locale)session.getAttribute(LOCALE); - if (locale == null) - { - locale = Locale.getDefault(); - } - bundle = ResourceBundleWrapper.getResourceBundle(MESSAGE_BUNDLE, locale); - - session.setAttribute(MESSAGE_BUNDLE, bundle); - } - - return bundle; - } - - /** - * Get the specified the default message bundle for this user - * - * @param context FacesContext - * - * @return ResourceBundle for this user - */ - public static ResourceBundle getBundle(FacesContext context) - { - // get the resource bundle for the current locale - // we store the bundle in the users session - // this makes it easy to add a locale per user support later - Map session = context.getExternalContext().getSessionMap(); - ResourceBundle bundle = (ResourceBundle)session.get(MESSAGE_BUNDLE); - if (bundle == null) - { - // get Locale from language selected by each user on login - Locale locale = (Locale)session.get(LOCALE); - if (locale == null) - { - locale = Locale.getDefault(); - } - bundle = ResourceBundleWrapper.getResourceBundle(MESSAGE_BUNDLE, locale); - - session.put(MESSAGE_BUNDLE, bundle); - } - - return bundle; - } - - /** - * Helper to get the ConfigService instance - * - * @param context FacesContext - * - * @return ConfigService - */ - public static ConfigService getConfigService(FacesContext context) - { - return (ConfigService)FacesContextUtils.getRequiredWebApplicationContext(context).getBean( - Application.BEAN_CONFIG_SERVICE); - } - - /** - * Helper to get the ConfigService instance - * - * @param context ServletContext - * - * @return ConfigService - */ - public static ConfigService getConfigService(ServletContext context) - { - return (ConfigService)WebApplicationContextUtils.getRequiredWebApplicationContext(context).getBean( - Application.BEAN_CONFIG_SERVICE); - } - - /** - * Helper to get the client config element from the config service - * - * @param context FacesContext - * @return The ClientConfigElement - */ - public static ClientConfigElement getClientConfig(FacesContext context) - { - return (ClientConfigElement)getConfigService(context).getGlobalConfig(). - getConfigElement(ClientConfigElement.CONFIG_ELEMENT_ID); - } - - /** - * Returns the repository store URL - * - * @param context The spring context - * @return The repository store URL to use - */ - private static StoreRef getRepositoryStoreRef(WebApplicationContext context) - { - if (repoStoreRef == null) - { - ImporterBootstrap bootstrap = (ImporterBootstrap)context.getBean(BEAN_IMPORTER_BOOTSTRAP); - repoStoreRef = bootstrap.getStoreRef(); - } - - return repoStoreRef; - } - - /** - * Returns the root path for the application - * - * @param context The spring context - * @return The application root path - */ - private static String getRootPath(WebApplicationContext context) - { - if (rootPath == null) - { - ImporterBootstrap bootstrap = (ImporterBootstrap)context.getBean(BEAN_IMPORTER_BOOTSTRAP); - Properties configuration = bootstrap.getConfiguration(); - rootPath = configuration.getProperty("spaces.company_home.childname"); - } - - return rootPath; - } - - /** - * Returns the glossary folder name - * - * @param context The spring context - * @return The glossary folder name - */ - private static String getGlossaryFolderName(WebApplicationContext context) - { - if (glossaryFolderName == null) - { - ImporterBootstrap bootstrap = (ImporterBootstrap)context.getBean(BEAN_IMPORTER_BOOTSTRAP); - Properties configuration = bootstrap.getConfiguration(); - glossaryFolderName = configuration.getProperty("spaces.dictionary.childname"); - } - - return glossaryFolderName; - } - - /** - * Returns the Space Templates folder name - * - * @param context The spring context - * @return The templates folder name - */ - private static String getSpaceTemplatesFolderName(WebApplicationContext context) - { - if (spaceTemplatesFolderName == null) - { - ImporterBootstrap bootstrap = (ImporterBootstrap)context.getBean(BEAN_IMPORTER_BOOTSTRAP); - Properties configuration = bootstrap.getConfiguration(); - spaceTemplatesFolderName = configuration.getProperty("spaces.templates.childname"); - } - - return spaceTemplatesFolderName; - } - - /** - * Returns the Content Templates folder name - * - * @param context The spring context - * @return The templates folder name - */ - private static String getContentTemplatesFolderName(WebApplicationContext context) - { - if (contentTemplatesFolderName == null) - { - ImporterBootstrap bootstrap = (ImporterBootstrap)context.getBean(BEAN_IMPORTER_BOOTSTRAP); - Properties configuration = bootstrap.getConfiguration(); - contentTemplatesFolderName = configuration.getProperty("spaces.templates.content.childname"); - } - - return contentTemplatesFolderName; - } - - /** - * Returns the Email Templates folder name - * - * @param context The spring context - * @return The email folder name - */ - private static String getEmailTemplatesFolderName(WebApplicationContext context) - { - if (emailTemplatesFolderName == null) - { - ImporterBootstrap bootstrap = (ImporterBootstrap)context.getBean(BEAN_IMPORTER_BOOTSTRAP); - Properties configuration = bootstrap.getConfiguration(); - emailTemplatesFolderName = configuration.getProperty("spaces.templates.email.childname"); - } - - return emailTemplatesFolderName; - } - - /** - * Returns the RSS Templates folder name - * - * @param context The spring context - * @return The RSS folder name - */ - private static String getRSSTemplatesFolderName(WebApplicationContext context) - { - if (rssTemplatesFolderName == null) - { - ImporterBootstrap bootstrap = (ImporterBootstrap)context.getBean(BEAN_IMPORTER_BOOTSTRAP); - Properties configuration = bootstrap.getConfiguration(); - rssTemplatesFolderName = configuration.getProperty("spaces.templates.rss.childname"); - } - - return rssTemplatesFolderName; - } - - /** - * Returns the Saved Searches folder name - * - * @param context The spring context - * @return The saved searches folder name - */ - private static String getSavedSearchesFolderName(WebApplicationContext context) - { - /* - * This lookup is duplicated in a patch. If this logic changes, investigate the changes - * required for the patch(es). - */ - - if (savedSearchesFolderName == null) - { - ImporterBootstrap bootstrap = (ImporterBootstrap)context.getBean(BEAN_IMPORTER_BOOTSTRAP); - Properties configuration = bootstrap.getConfiguration(); - savedSearchesFolderName = configuration.getProperty("spaces.savedsearches.childname"); - } - - return savedSearchesFolderName; - } - - /** - * Returns the JavaScript scripts folder name - * - * @param context The spring context - * @return The scripts folder name - */ - private static String getScriptsFolderName(WebApplicationContext context) - { - if (scriptsFolderName == null) - { - ImporterBootstrap bootstrap = (ImporterBootstrap)context.getBean(BEAN_IMPORTER_BOOTSTRAP); - Properties configuration = bootstrap.getConfiguration(); - scriptsFolderName = configuration.getProperty("spaces.scripts.childname"); - } - - return scriptsFolderName; - } - - /** - * Returns the Guest Home folder name - * - * @param context The spring context - * @return The Guest Home folder name - */ - private static String getGuestHomeFolderName(WebApplicationContext context) - { - if (guestHomeFolderName == null) - { - ImporterBootstrap bootstrap = (ImporterBootstrap)context.getBean(BEAN_IMPORTER_BOOTSTRAP); - Properties configuration = bootstrap.getConfiguration(); - guestHomeFolderName = configuration.getProperty("spaces.guest_home.childname"); - } - - return guestHomeFolderName; - } - - /** - * Returns the Websites folder name - * - * @param context The Spring context - * @return The Websites folder name - */ - private static String getWebsitesFolderName(WebApplicationContext context) - { - if (websitesFolderName == null) - { - ImporterBootstrap bootstrap = (ImporterBootstrap)context.getBean(BEAN_IMPORTER_BOOTSTRAP); - Properties configuration = bootstrap.getConfiguration(); - websitesFolderName = configuration.getProperty("spaces.wcm.childname"); - } - - return websitesFolderName; - } - - /** - * Retrieves the configured error page for the application - * - * @param context The Spring context - * @return The configured error page or null if the configuration is missing - */ - private static String getErrorPage(WebApplicationContext context) - { - String errorPage = null; - - ConfigService svc = (ConfigService)context.getBean(BEAN_CONFIG_SERVICE); - ClientConfigElement clientConfig = (ClientConfigElement)svc.getGlobalConfig(). - getConfigElement(ClientConfigElement.CONFIG_ELEMENT_ID); - - if (clientConfig != null) - { - errorPage = clientConfig.getErrorPage(); - } - - return errorPage; - } - - /** - * Retrieves the configured login page for the application - * - * @param context The Spring contexr - * @return The configured login page or null if the configuration is missing - */ - private static String getLoginPage(WebApplicationContext context) - { - String loginPage = null; - - ConfigService svc = (ConfigService)context.getBean(BEAN_CONFIG_SERVICE); - ClientConfigElement clientConfig = (ClientConfigElement)svc.getGlobalConfig(). - getConfigElement(ClientConfigElement.CONFIG_ELEMENT_ID); - - if (clientConfig != null) - { - loginPage = clientConfig.getLoginPage(); - } - - return loginPage; - } -} +/* + * Copyright (C) 2005 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ +package org.alfresco.web.app; + +import java.io.IOException; +import java.util.Locale; +import java.util.Map; +import java.util.Properties; +import java.util.ResourceBundle; +import java.util.StringTokenizer; + +import javax.faces.context.FacesContext; +import javax.portlet.PortletContext; +import javax.portlet.PortletSession; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.alfresco.config.ConfigService; +import org.alfresco.repo.importer.ImporterBootstrap; +import org.alfresco.service.cmr.repository.StoreRef; +import org.alfresco.web.app.servlet.AuthenticationHelper; +import org.alfresco.web.app.servlet.FacesHelper; +import org.alfresco.web.bean.ErrorBean; +import org.alfresco.web.bean.dashboard.DashboardManager; +import org.alfresco.web.bean.dialog.DialogManager; +import org.alfresco.web.bean.repository.User; +import org.alfresco.web.bean.wizard.WizardManager; +import org.alfresco.web.config.ClientConfigElement; +import org.apache.commons.logging.Log; +import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.context.support.WebApplicationContextUtils; +import org.springframework.web.jsf.FacesContextUtils; + +/** + * Utilities class + * + * @author gavinc + */ +public class Application +{ + private static final String LOCALE = "locale"; + + public static final String BEAN_CONFIG_SERVICE = "webClientConfigService"; + public static final String BEAN_DATA_DICTIONARY = "dataDictionary"; + public static final String BEAN_IMPORTER_BOOTSTRAP = "spacesBootstrap"; + + public static final String MESSAGE_BUNDLE = "alfresco.messages.webclient"; + + private static boolean inPortalServer = false; + private static StoreRef repoStoreRef; + private static String rootPath; + private static String companyRootId; + private static String glossaryFolderName; + private static String spaceTemplatesFolderName; + private static String contentTemplatesFolderName; + private static String emailTemplatesFolderName; + private static String rssTemplatesFolderName; + private static String savedSearchesFolderName; + private static String scriptsFolderName; + private static String guestHomeFolderName; + private static String websitesFolderName; + + /** + * Private constructor to prevent instantiation of this class + */ + private Application() + { + } + + /** + * Sets whether this application is running inside a portal server + * + * @param inPortal true to indicate the application is running as a portlet + */ + public static void setInPortalServer(boolean inPortal) + { + inPortalServer = inPortal; + } + + /** + * Determines whether the server is running in a portal + * + * @return true if we are running inside a portal server + */ + public static boolean inPortalServer() + { + return inPortalServer; + } + + /** + * Handles errors thrown from servlets + * + * @param servletContext The servlet context + * @param request The HTTP request + * @param response The HTTP response + * @param error The exception + * @param logger The logger + */ + public static void handleServletError(ServletContext servletContext, HttpServletRequest request, + HttpServletResponse response, Throwable error, Log logger, String returnPage) + throws IOException, ServletException + { + // get the error bean from the session and set the error that occurred. + HttpSession session = request.getSession(); + ErrorBean errorBean = (ErrorBean)session.getAttribute(ErrorBean.ERROR_BEAN_NAME); + if (errorBean == null) + { + errorBean = new ErrorBean(); + session.setAttribute(ErrorBean.ERROR_BEAN_NAME, errorBean); + } + errorBean.setLastError(error); + errorBean.setReturnPage(returnPage); + + // try and find the configured error page + boolean errorShown = false; + String errorPage = getErrorPage(servletContext); + + if (errorPage != null) + { + if (logger.isDebugEnabled()) + logger.debug("An error has occurred, redirecting to error page: " + errorPage); + + if (response.isCommitted() == false) + { + errorShown = true; + response.sendRedirect(request.getContextPath() + errorPage); + } + else + { + if (logger.isDebugEnabled()) + logger.debug("Response is already committed, re-throwing error"); + } + } + else + { + if (logger.isDebugEnabled()) + logger.debug("No error page defined, re-throwing error"); + } + + // if we could not show the error page for whatever reason, re-throw the error + if (!errorShown) + { + if (error instanceof IOException) + { + throw (IOException)error; + } + else if (error instanceof ServletException) + { + throw (ServletException)error; + } + else + { + throw new ServletException(error); + } + } + } + + /** + * Retrieves the DialogManager managed bean + * + * @return DialogManager bean + */ + public static DialogManager getDialogManager() + { + return (DialogManager)FacesHelper.getManagedBean(FacesContext.getCurrentInstance(), "DialogManager"); + } + + /** + * Retrieves the WizardManager managed bean + * + * @return WizardManager bean + */ + public static WizardManager getWizardManager() + { + return (WizardManager)FacesHelper.getManagedBean(FacesContext.getCurrentInstance(), "WizardManager"); + } + + /** + * Retrieves the DashboardManager managed bean + * + * @return DashboardManager bean + */ + public static DashboardManager getDashboardManager() + { + return (DashboardManager)FacesHelper.getManagedBean(FacesContext.getCurrentInstance(), "DashboardManager"); + } + + /** + * Retrieves the configured error page for the application + * + * @param servletContext The servlet context + * @return The configured error page or null if the configuration is missing + */ + public static String getErrorPage(ServletContext servletContext) + { + return getErrorPage(WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext)); + } + + /** + * Retrieves the configured error page for the application + * + * @param portletContext The portlet context + * @return + */ + public static String getErrorPage(PortletContext portletContext) + { + return getErrorPage((WebApplicationContext)portletContext.getAttribute( + WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE)); + } + + /** + * Retrieves the configured login page for the application + * + * @param servletContext The servlet context + * @return The configured login page or null if the configuration is missing + */ + public static String getLoginPage(ServletContext servletContext) + { + return getLoginPage(WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext)); + } + + /** + * Retrieves the configured login page for the application + * + * @param portletContext The portlet context + * @return + */ + public static String getLoginPage(PortletContext portletContext) + { + return getLoginPage((WebApplicationContext)portletContext.getAttribute( + WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE)); + } + + /** + * @return Returns the User object representing the currently logged in user + */ + public static User getCurrentUser(HttpSession session) + { + return (User)session.getAttribute(AuthenticationHelper.AUTHENTICATION_USER); + } + + /** + * @return Returns the User object representing the currently logged in user + */ + public static User getCurrentUser(FacesContext context) + { + return (User)context.getExternalContext().getSessionMap().get(AuthenticationHelper.AUTHENTICATION_USER); + } + + /** + * @return Returns the repository store URL (retrieved from config service) + */ + public static StoreRef getRepositoryStoreRef(ServletContext context) + { + return getRepositoryStoreRef(WebApplicationContextUtils.getRequiredWebApplicationContext(context)); + } + + /** + * @return Returns the repository store URL (retrieved from config service) + */ + public static StoreRef getRepositoryStoreRef(FacesContext context) + { + return getRepositoryStoreRef(FacesContextUtils.getRequiredWebApplicationContext(context)); + } + + /** + * @return Returns id of the company root + */ + public static String getCompanyRootId() + { + return companyRootId; + } + + /** + * Sets the company root id. This is setup by the ContextListener. + * + * @param id The company root id + */ + public static void setCompanyRootId(String id) + { + companyRootId = id; + } + + /** + * @return Returns the root path for the application + */ + public static String getRootPath(ServletContext context) + { + return getRootPath(WebApplicationContextUtils.getRequiredWebApplicationContext(context)); + } + + /** + * @return Returns the root path for the application + */ + public static String getRootPath(FacesContext context) + { + return getRootPath(FacesContextUtils.getRequiredWebApplicationContext(context)); + } + + /** + * @return Returns the glossary folder name + */ + public static String getGlossaryFolderName(ServletContext context) + { + return getGlossaryFolderName(WebApplicationContextUtils.getRequiredWebApplicationContext(context)); + } + + /** + * @return Returns the glossary folder name + */ + public static String getGlossaryFolderName(FacesContext context) + { + return getGlossaryFolderName(FacesContextUtils.getRequiredWebApplicationContext(context)); + } + + /** + * @return Returns the Space templates folder name + */ + public static String getSpaceTemplatesFolderName(ServletContext context) + { + return getSpaceTemplatesFolderName(WebApplicationContextUtils.getRequiredWebApplicationContext(context)); + } + + /** + * @return Returns the Space templates folder name + */ + public static String getSpaceTemplatesFolderName(FacesContext context) + { + return getSpaceTemplatesFolderName(FacesContextUtils.getRequiredWebApplicationContext(context)); + } + + /** + * @return Returns the Content templates folder name + */ + public static String getContentTemplatesFolderName(ServletContext context) + { + return getContentTemplatesFolderName(WebApplicationContextUtils.getRequiredWebApplicationContext(context)); + } + + /** + * @return Returns the Content templates folder name + */ + public static String getContentTemplatesFolderName(FacesContext context) + { + return getContentTemplatesFolderName(FacesContextUtils.getRequiredWebApplicationContext(context)); + } + + /** + * @return Returns the Email templates folder name + */ + public static String getEmailTemplatesFolderName(ServletContext context) + { + return getEmailTemplatesFolderName(WebApplicationContextUtils.getRequiredWebApplicationContext(context)); + } + + /** + * @return Returns the Email templates folder name + */ + public static String getEmailTemplatesFolderName(FacesContext context) + { + return getEmailTemplatesFolderName(FacesContextUtils.getRequiredWebApplicationContext(context)); + } + + /** + * @return Returns the RSS templates folder name + */ + public static String getRSSTemplatesFolderName(ServletContext context) + { + return getRSSTemplatesFolderName(WebApplicationContextUtils.getRequiredWebApplicationContext(context)); + } + + /** + * @return Returns the RSS templates folder name + */ + public static String getRSSTemplatesFolderName(FacesContext context) + { + return getRSSTemplatesFolderName(FacesContextUtils.getRequiredWebApplicationContext(context)); + } + + /** + * @return Return the Saved Searches folder name + */ + public static String getSavedSearchesFolderName(ServletContext context) + { + return getSavedSearchesFolderName(WebApplicationContextUtils.getRequiredWebApplicationContext(context)); + } + + /** + * @return Return the Saved Searches folder name + */ + public static String getSavedSearchesFolderName(FacesContext context) + { + return getSavedSearchesFolderName(FacesContextUtils.getRequiredWebApplicationContext(context)); + } + + /** + * @return Return the JavaScript scripts folder name + */ + public static String getScriptsFolderName(ServletContext context) + { + return getScriptsFolderName(WebApplicationContextUtils.getRequiredWebApplicationContext(context)); + } + + /** + * @return Return the JavaScript scripts folder name + */ + public static String getScriptsFolderName(FacesContext context) + { + return getScriptsFolderName(FacesContextUtils.getRequiredWebApplicationContext(context)); + } + + /** + * @return Return the Guest Home folder name + */ + public static String getGuestHomeFolderName(ServletContext context) + { + return getGuestHomeFolderName(WebApplicationContextUtils.getRequiredWebApplicationContext(context)); + } + + /** + * @return Return the Guest Home folder name + */ + public static String getGuestHomeFolderName(FacesContext context) + { + return getGuestHomeFolderName(FacesContextUtils.getRequiredWebApplicationContext(context)); + } + + /** + * @return the Websites folder name + */ + public static String getWebsitesFolderName(ServletContext context) + { + return getWebsitesFolderName(WebApplicationContextUtils.getRequiredWebApplicationContext(context)); + } + + /** + * @return the Websites folder name + */ + public static String getWebsitesFolderName(FacesContext context) + { + return getWebsitesFolderName(FacesContextUtils.getRequiredWebApplicationContext(context)); + } + + /** + * Set the language locale for the current user context + * + * @param context FacesContext for current user + * @param code The ISO locale code to set + */ + public static void setLanguage(FacesContext context, String code) + { + Locale locale = parseLocale(code); + + // set locale for JSF framework usage + context.getViewRoot().setLocale(locale); + + // set locale for our framework usage + context.getExternalContext().getSessionMap().put(LOCALE, locale); + + // clear the current message bundle - so it's reloaded with new locale + context.getExternalContext().getSessionMap().remove(MESSAGE_BUNDLE); + } + + /** + * Set the language locale for the current user session + * + * @param session HttpSession for current user + * @param code The ISO locale code to set + */ + public static void setLanguage(HttpSession session, String code) + { + Locale locale = parseLocale(code); + + session.putValue(LOCALE, locale); + session.removeAttribute(MESSAGE_BUNDLE); + } + + /** + * @param code Locale code (java format with underscores) to parse + * @return Locale object or default if unable to parse + */ + private static Locale parseLocale(String code) + { + Locale locale = Locale.getDefault(); + + StringTokenizer t = new StringTokenizer(code, "_"); + int tokens = t.countTokens(); + if (tokens == 1) + { + locale = new Locale(code); + } + else if (tokens == 2) + { + locale = new Locale(t.nextToken(), t.nextToken()); + } + else if (tokens == 3) + { + locale = new Locale(t.nextToken(), t.nextToken(), t.nextToken()); + } + + return locale; + } + + /** + * Return the language Locale for the current user context + * + * @param context FacesContext for the current user + * + * @return Current language Locale set or the VM default if none set + */ + public static Locale getLanguage(FacesContext context) + { + Locale locale = (Locale)context.getExternalContext().getSessionMap().get(LOCALE); + return locale != null ? locale : Locale.getDefault(); + } + + /** + * Return the language Locale for the current user Session. + * + * @param session HttpSession for the current user + * + * @return Current language Locale set or the VM default if none set + */ + public static Locale getLanguage(HttpSession session) + { + Locale locale = (Locale)session.getAttribute(LOCALE); + return locale != null ? locale : Locale.getDefault(); + } + + /** + * Return the language Locale for the current user PortletSession. + * + * @param session PortletSession for the current user + * + * @return Current language Locale set or the VM default if none set + */ + public static Locale getLanguage(PortletSession session) + { + Locale locale = (Locale)session.getAttribute(LOCALE); + return locale != null ? locale : Locale.getDefault(); + } + + /** + * Get the specified I18N message string from the default message bundle for this user + * + * @param context FacesContext + * @param msg Message ID + * + * @return String from message bundle or $$msg$$ if not found + */ + public static String getMessage(FacesContext context, String msg) + { + return getBundle(context).getString(msg); + } + + /** + * Get the specified I18N message string from the default message bundle for this user + * + * @param session HttpSession + * @param msg Message ID + * + * @return String from message bundle or $$msg$$ if not found + */ + public static String getMessage(HttpSession session, String msg) + { + return getBundle(session).getString(msg); + } + + /** + * Get the specified the default message bundle for this user + * + * @param session HttpSession + * + * @return ResourceBundle for this user + */ + public static ResourceBundle getBundle(HttpSession session) + { + ResourceBundle bundle = (ResourceBundle)session.getAttribute(MESSAGE_BUNDLE); + if (bundle == null) + { + // get Locale from language selected by each user on login + Locale locale = (Locale)session.getAttribute(LOCALE); + if (locale == null) + { + locale = Locale.getDefault(); + } + bundle = ResourceBundleWrapper.getResourceBundle(MESSAGE_BUNDLE, locale); + + session.setAttribute(MESSAGE_BUNDLE, bundle); + } + + return bundle; + } + + /** + * Get the specified the default message bundle for this user + * + * @param context FacesContext + * + * @return ResourceBundle for this user + */ + public static ResourceBundle getBundle(FacesContext context) + { + // get the resource bundle for the current locale + // we store the bundle in the users session + // this makes it easy to add a locale per user support later + Map session = context.getExternalContext().getSessionMap(); + ResourceBundle bundle = (ResourceBundle)session.get(MESSAGE_BUNDLE); + if (bundle == null) + { + // get Locale from language selected by each user on login + Locale locale = (Locale)session.get(LOCALE); + if (locale == null) + { + locale = Locale.getDefault(); + } + bundle = ResourceBundleWrapper.getResourceBundle(MESSAGE_BUNDLE, locale); + + session.put(MESSAGE_BUNDLE, bundle); + } + + return bundle; + } + + /** + * Helper to get the ConfigService instance + * + * @param context FacesContext + * + * @return ConfigService + */ + public static ConfigService getConfigService(FacesContext context) + { + return (ConfigService)FacesContextUtils.getRequiredWebApplicationContext(context).getBean( + Application.BEAN_CONFIG_SERVICE); + } + + /** + * Helper to get the ConfigService instance + * + * @param context ServletContext + * + * @return ConfigService + */ + public static ConfigService getConfigService(ServletContext context) + { + return (ConfigService)WebApplicationContextUtils.getRequiredWebApplicationContext(context).getBean( + Application.BEAN_CONFIG_SERVICE); + } + + /** + * Helper to get the client config element from the config service + * + * @param context FacesContext + * @return The ClientConfigElement + */ + public static ClientConfigElement getClientConfig(FacesContext context) + { + return (ClientConfigElement)getConfigService(context).getGlobalConfig(). + getConfigElement(ClientConfigElement.CONFIG_ELEMENT_ID); + } + + /** + * Returns the repository store URL + * + * @param context The spring context + * @return The repository store URL to use + */ + private static StoreRef getRepositoryStoreRef(WebApplicationContext context) + { + if (repoStoreRef == null) + { + ImporterBootstrap bootstrap = (ImporterBootstrap)context.getBean(BEAN_IMPORTER_BOOTSTRAP); + repoStoreRef = bootstrap.getStoreRef(); + } + + return repoStoreRef; + } + + /** + * Returns the root path for the application + * + * @param context The spring context + * @return The application root path + */ + private static String getRootPath(WebApplicationContext context) + { + if (rootPath == null) + { + ImporterBootstrap bootstrap = (ImporterBootstrap)context.getBean(BEAN_IMPORTER_BOOTSTRAP); + Properties configuration = bootstrap.getConfiguration(); + rootPath = configuration.getProperty("spaces.company_home.childname"); + } + + return rootPath; + } + + /** + * Returns the glossary folder name + * + * @param context The spring context + * @return The glossary folder name + */ + private static String getGlossaryFolderName(WebApplicationContext context) + { + if (glossaryFolderName == null) + { + ImporterBootstrap bootstrap = (ImporterBootstrap)context.getBean(BEAN_IMPORTER_BOOTSTRAP); + Properties configuration = bootstrap.getConfiguration(); + glossaryFolderName = configuration.getProperty("spaces.dictionary.childname"); + } + + return glossaryFolderName; + } + + /** + * Returns the Space Templates folder name + * + * @param context The spring context + * @return The templates folder name + */ + private static String getSpaceTemplatesFolderName(WebApplicationContext context) + { + if (spaceTemplatesFolderName == null) + { + ImporterBootstrap bootstrap = (ImporterBootstrap)context.getBean(BEAN_IMPORTER_BOOTSTRAP); + Properties configuration = bootstrap.getConfiguration(); + spaceTemplatesFolderName = configuration.getProperty("spaces.templates.childname"); + } + + return spaceTemplatesFolderName; + } + + /** + * Returns the Content Templates folder name + * + * @param context The spring context + * @return The templates folder name + */ + private static String getContentTemplatesFolderName(WebApplicationContext context) + { + if (contentTemplatesFolderName == null) + { + ImporterBootstrap bootstrap = (ImporterBootstrap)context.getBean(BEAN_IMPORTER_BOOTSTRAP); + Properties configuration = bootstrap.getConfiguration(); + contentTemplatesFolderName = configuration.getProperty("spaces.templates.content.childname"); + } + + return contentTemplatesFolderName; + } + + /** + * Returns the Email Templates folder name + * + * @param context The spring context + * @return The email folder name + */ + private static String getEmailTemplatesFolderName(WebApplicationContext context) + { + if (emailTemplatesFolderName == null) + { + ImporterBootstrap bootstrap = (ImporterBootstrap)context.getBean(BEAN_IMPORTER_BOOTSTRAP); + Properties configuration = bootstrap.getConfiguration(); + emailTemplatesFolderName = configuration.getProperty("spaces.templates.email.childname"); + } + + return emailTemplatesFolderName; + } + + /** + * Returns the RSS Templates folder name + * + * @param context The spring context + * @return The RSS folder name + */ + private static String getRSSTemplatesFolderName(WebApplicationContext context) + { + if (rssTemplatesFolderName == null) + { + ImporterBootstrap bootstrap = (ImporterBootstrap)context.getBean(BEAN_IMPORTER_BOOTSTRAP); + Properties configuration = bootstrap.getConfiguration(); + rssTemplatesFolderName = configuration.getProperty("spaces.templates.rss.childname"); + } + + return rssTemplatesFolderName; + } + + /** + * Returns the Saved Searches folder name + * + * @param context The spring context + * @return The saved searches folder name + */ + private static String getSavedSearchesFolderName(WebApplicationContext context) + { + /* + * This lookup is duplicated in a patch. If this logic changes, investigate the changes + * required for the patch(es). + */ + + if (savedSearchesFolderName == null) + { + ImporterBootstrap bootstrap = (ImporterBootstrap)context.getBean(BEAN_IMPORTER_BOOTSTRAP); + Properties configuration = bootstrap.getConfiguration(); + savedSearchesFolderName = configuration.getProperty("spaces.savedsearches.childname"); + } + + return savedSearchesFolderName; + } + + /** + * Returns the JavaScript scripts folder name + * + * @param context The spring context + * @return The scripts folder name + */ + private static String getScriptsFolderName(WebApplicationContext context) + { + if (scriptsFolderName == null) + { + ImporterBootstrap bootstrap = (ImporterBootstrap)context.getBean(BEAN_IMPORTER_BOOTSTRAP); + Properties configuration = bootstrap.getConfiguration(); + scriptsFolderName = configuration.getProperty("spaces.scripts.childname"); + } + + return scriptsFolderName; + } + + /** + * Returns the Guest Home folder name + * + * @param context The spring context + * @return The Guest Home folder name + */ + private static String getGuestHomeFolderName(WebApplicationContext context) + { + if (guestHomeFolderName == null) + { + ImporterBootstrap bootstrap = (ImporterBootstrap)context.getBean(BEAN_IMPORTER_BOOTSTRAP); + Properties configuration = bootstrap.getConfiguration(); + guestHomeFolderName = configuration.getProperty("spaces.guest_home.childname"); + } + + return guestHomeFolderName; + } + + /** + * Returns the Websites folder name + * + * @param context The Spring context + * @return The Websites folder name + */ + private static String getWebsitesFolderName(WebApplicationContext context) + { + if (websitesFolderName == null) + { + ImporterBootstrap bootstrap = (ImporterBootstrap)context.getBean(BEAN_IMPORTER_BOOTSTRAP); + Properties configuration = bootstrap.getConfiguration(); + websitesFolderName = configuration.getProperty("spaces.wcm.childname"); + } + + return websitesFolderName; + } + + /** + * Retrieves the configured error page for the application + * + * @param context The Spring context + * @return The configured error page or null if the configuration is missing + */ + private static String getErrorPage(WebApplicationContext context) + { + String errorPage = null; + + ConfigService svc = (ConfigService)context.getBean(BEAN_CONFIG_SERVICE); + ClientConfigElement clientConfig = (ClientConfigElement)svc.getGlobalConfig(). + getConfigElement(ClientConfigElement.CONFIG_ELEMENT_ID); + + if (clientConfig != null) + { + errorPage = clientConfig.getErrorPage(); + } + + return errorPage; + } + + /** + * Retrieves the configured login page for the application + * + * @param context The Spring contexr + * @return The configured login page or null if the configuration is missing + */ + private static String getLoginPage(WebApplicationContext context) + { + String loginPage = null; + + ConfigService svc = (ConfigService)context.getBean(BEAN_CONFIG_SERVICE); + ClientConfigElement clientConfig = (ClientConfigElement)svc.getGlobalConfig(). + getConfigElement(ClientConfigElement.CONFIG_ELEMENT_ID); + + if (clientConfig != null) + { + loginPage = clientConfig.getLoginPage(); + } + + return loginPage; + } +} diff --git a/source/java/org/alfresco/web/bean/BrowseBean.java b/source/java/org/alfresco/web/bean/BrowseBean.java index b163b6b20f..4fa7ded19a 100644 --- a/source/java/org/alfresco/web/bean/BrowseBean.java +++ b/source/java/org/alfresco/web/bean/BrowseBean.java @@ -1,1708 +1,1741 @@ -/* - * Copyright (C) 2005 Alfresco, Inc. - * - * Licensed under the Mozilla Public License version 1.1 - * with a permitted attribution clause. You may obtain a - * copy of the License at - * - * http://www.alfresco.org/legal/license.txt - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, - * either express or implied. See the License for the specific - * language governing permissions and limitations under the - * License. - */ -package org.alfresco.web.bean; - -import java.text.MessageFormat; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import javax.faces.application.FacesMessage; -import javax.faces.context.FacesContext; -import javax.faces.event.ActionEvent; -import javax.transaction.UserTransaction; - -import org.alfresco.config.Config; -import org.alfresco.config.ConfigElement; -import org.alfresco.config.ConfigService; -import org.alfresco.model.ContentModel; -import org.alfresco.service.cmr.dictionary.DictionaryService; -import org.alfresco.service.cmr.dictionary.TypeDefinition; -import org.alfresco.service.cmr.lock.LockService; -import org.alfresco.service.cmr.model.FileFolderService; -import org.alfresco.service.cmr.repository.ChildAssociationRef; -import org.alfresco.service.cmr.repository.ContentData; -import org.alfresco.service.cmr.repository.InvalidNodeRefException; -import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.cmr.repository.NodeService; -import org.alfresco.service.cmr.repository.Path; -import org.alfresco.service.cmr.search.LimitBy; -import org.alfresco.service.cmr.search.ResultSet; -import org.alfresco.service.cmr.search.ResultSetRow; -import org.alfresco.service.cmr.search.SearchParameters; -import org.alfresco.service.cmr.search.SearchService; -import org.alfresco.service.namespace.QName; -import org.alfresco.service.namespace.RegexQNamePattern; -import org.alfresco.web.app.AlfrescoNavigationHandler; -import org.alfresco.web.app.Application; -import org.alfresco.web.app.context.IContextListener; -import org.alfresco.web.app.context.UIContextService; -import org.alfresco.web.app.servlet.DownloadContentServlet; -import org.alfresco.web.app.servlet.FacesHelper; -import org.alfresco.web.bean.repository.MapNode; -import org.alfresco.web.bean.repository.Node; -import org.alfresco.web.bean.repository.NodePropertyResolver; -import org.alfresco.web.bean.repository.QNameNodeMap; -import org.alfresco.web.bean.repository.Repository; -import org.alfresco.web.bean.spaces.CreateSpaceWizard; -import org.alfresco.web.config.ViewsConfigElement; -import org.alfresco.web.ui.common.Utils; -import org.alfresco.web.ui.common.Utils.URLMode; -import org.alfresco.web.ui.common.component.IBreadcrumbHandler; -import org.alfresco.web.ui.common.component.UIActionLink; -import org.alfresco.web.ui.common.component.UIBreadcrumb; -import org.alfresco.web.ui.common.component.UIModeList; -import org.alfresco.web.ui.common.component.UIStatusMessage; -import org.alfresco.web.ui.common.component.data.UIRichList; -import org.alfresco.web.ui.repo.component.IRepoBreadcrumbHandler; -import org.alfresco.web.ui.repo.component.UINodeDescendants; -import org.alfresco.web.ui.repo.component.UINodePath; -import org.alfresco.web.ui.repo.component.UISimpleSearch; -import org.apache.log4j.Logger; -import org.apache.log4j.Priority; - -/** - * Bean providing properties and behaviour for the main folder/document browse screen and - * search results screens. - * - * @author Kevin Roast - */ -public class BrowseBean implements IContextListener -{ - // ------------------------------------------------------------------------------ - // Construction - - /** - * Default Constructor - */ - public BrowseBean() - { - UIContextService.getInstance(FacesContext.getCurrentInstance()).registerBean(this); - - initFromClientConfig(); - } - - - // ------------------------------------------------------------------------------ - // Bean property getters and setters - - /** - * @param nodeService The NodeService to set. - */ - public void setNodeService(NodeService nodeService) - { - this.nodeService = nodeService; - } - - /** - * @param searchService The Searcher to set. - */ - public void setSearchService(SearchService searchService) - { - this.searchService = searchService; - } - - /** - * @param lockService The Lock Service to set. - */ - public void setLockService(LockService lockService) - { - this.lockService = lockService; - } - - /** - * @param navigator The NavigationBean to set. - */ - public void setNavigator(NavigationBean navigator) - { - this.navigator = navigator; - } - - /** - * @param dictionaryService The DictionaryService to set. - */ - public void setDictionaryService(DictionaryService dictionaryService) - { - this.dictionaryService = dictionaryService; - } - - /** - * @param fileFolderService The FileFolderService to set. - */ - public void setFileFolderService(FileFolderService fileFolderService) - { - this.fileFolderService = fileFolderService; - } - - /** - * @return Returns the browse View mode. See UIRichList - */ - public String getBrowseViewMode() - { - return this.browseViewMode; - } - - /** - * @param browseViewMode The browse View mode to set. See UIRichList. - */ - public void setBrowseViewMode(String browseViewMode) - { - this.browseViewMode = browseViewMode; - } - - /** - * @return Returns true if dashboard view is available for the current node. - */ - public boolean isDashboardView() - { - return this.dashboardView; - } - - /** - * @param dashboardView The dashboard view mode to set. - */ - public void setDashboardView(boolean dashboardView) - { - this.dashboardView = dashboardView; - if (dashboardView == true) - { - FacesContext fc = FacesContext.getCurrentInstance(); - fc.getApplication().getNavigationHandler().handleNavigation(fc, null, "dashboard"); - } - } - - public int getPageSizeContent() - { - return this.pageSizeContent; - } - - public void setPageSizeContent(int pageSizeContent) - { - this.pageSizeContent = pageSizeContent; - this.pageSizeContentStr = Integer.toString(pageSizeContent); - } - - public int getPageSizeSpaces() - { - return this.pageSizeSpaces; - } - - public void setPageSizeSpaces(int pageSizeSpaces) - { - this.pageSizeSpaces = pageSizeSpaces; - this.pageSizeSpacesStr = Integer.toString(pageSizeSpaces); - } - - public String getPageSizeContentStr() - { - return this.pageSizeContentStr; - } - - public void setPageSizeContentStr(String pageSizeContentStr) - { - this.pageSizeContentStr = pageSizeContentStr; - } - - public String getPageSizeSpacesStr() - { - return this.pageSizeSpacesStr; - } - - public void setPageSizeSpacesStr(String pageSizeSpacesStr) - { - this.pageSizeSpacesStr = pageSizeSpacesStr; - } - - /** - * @return Returns the minimum length of a valid search string. - */ - public int getMinimumSearchLength() - { - return Application.getClientConfig(FacesContext.getCurrentInstance()). - getSearchMinimum(); - } - - /** - * @return Returns the Space Node being used for the current browse screen action. - */ - public Node getActionSpace() - { - return this.actionSpace; - } - - /** - * @param actionSpace Set the Space Node to be used for the current browse screen action. - */ - public void setActionSpace(Node actionSpace) - { - if (actionSpace != null) - { - for (NodeEventListener listener : getNodeEventListeners()) - { - listener.created(actionSpace, actionSpace.getType()); - } - } - this.actionSpace = actionSpace; - } - - /** - * @return The document node being used for the current operation - */ - public Node getDocument() - { - return this.document; - } - - /** - * @param document The document node to be used for the current operation - */ - public void setDocument(Node document) - { - if (document != null) - { - for (NodeEventListener listener : getNodeEventListeners()) - { - listener.created(document, document.getType()); - } - } - this.document = document; - } - - /** - * @param contentRichList The contentRichList to set. - */ - public void setContentRichList(UIRichList browseRichList) - { - this.contentRichList = browseRichList; - if (this.contentRichList != null) - { - this.contentRichList.setInitialSortColumn( - this.viewsConfig.getDefaultSortColumn(PAGE_NAME_BROWSE)); - this.contentRichList.setInitialSortDescending( - this.viewsConfig.hasDescendingSort(PAGE_NAME_BROWSE)); - } - // special case to handle an External Access URL - // these URLs restart the JSF lifecycle but an old UIRichList is restored from - // the component tree - which needs clearing "late" in the lifecycle process - if (externalForceRefresh) - { - this.contentRichList.setValue(null); - externalForceRefresh = false; - } - } - - /** - * @return Returns the contentRichList. - */ - public UIRichList getContentRichList() - { - return this.contentRichList; - } - - /** - * @param spacesRichList The spacesRichList to set. - */ - public void setSpacesRichList(UIRichList detailsRichList) - { - this.spacesRichList = detailsRichList; - if (this.spacesRichList != null) - { - // set the initial sort column and direction - this.spacesRichList.setInitialSortColumn( - this.viewsConfig.getDefaultSortColumn(PAGE_NAME_BROWSE)); - this.spacesRichList.setInitialSortDescending( - this.viewsConfig.hasDescendingSort(PAGE_NAME_BROWSE)); - } - if (externalForceRefresh) - { - this.spacesRichList.setValue(null); - } - } - - /** - * @return Returns the spacesRichList. - */ - public UIRichList getSpacesRichList() - { - return this.spacesRichList; - } - - /** - * @return Returns the statusMessage component. - */ - public UIStatusMessage getStatusMessage() - { - return this.statusMessage; - } - - /** - * @param statusMessage The statusMessage component to set. - */ - public void setStatusMessage(UIStatusMessage statusMessage) - { - this.statusMessage = statusMessage; - } - - /** - * @return Returns the deleteMessage. - */ - public String getDeleteMessage() - { - return this.deleteMessage; - } - - /** - * @param deleteMessage The deleteMessage to set. - */ - public void setDeleteMessage(String deleteMessage) - { - this.deleteMessage = deleteMessage; - } - - /** - * Page accessed bean method to get the container nodes currently being browsed - * - * @return List of container Node objects for the current browse location - */ - public List getNodes() - { - // the references to container nodes and content nodes are transient for one use only - // we do this so we only query/search once - as we cannot distinguish between node types - // until after the query. The logic is a bit confusing but otherwise we would need to - // perform the same query or search twice for every screen refresh. - if (this.containerNodes == null) - { - if (this.navigator.getSearchContext() == null) - { - queryBrowseNodes(this.navigator.getCurrentNodeId()); - } - else - { - searchBrowseNodes(this.navigator.getSearchContext()); - } - } - List result = this.containerNodes; - - // we clear the member variable during invalidateComponents() - - return result; - } - - /** - * Page accessed bean method to get the content nodes currently being browsed - * - * @return List of content Node objects for the current browse location - */ - public List getContent() - { - // see comment in getNodes() above for reasoning here - if (this.contentNodes == null) - { - if (this.navigator.getSearchContext() == null) - { - queryBrowseNodes(this.navigator.getCurrentNodeId()); - } - else - { - searchBrowseNodes(this.navigator.getSearchContext()); - } - } - List result = this.contentNodes; - - // we clear the member variable during invalidateComponents() - - return result; - } - - /** - * Setup the common properties required at data-binding time. - *

- * These are properties used by components on the page when iterating over the nodes. - * The properties are available as the Node is a Map so they can be accessed directly - * by name. Information such as download URL, size and filetype are provided etc. - *

- * We use a set of anonymous inner classes to provide the implemention for the property - * getters. The interfaces are only called when the properties are first requested. - * - * @param node Node to add the properties too - */ - public void setupCommonBindingProperties(Node node) - { - // special properties to be used by the value binding components on the page - node.addPropertyResolver("url", this.resolverUrl); - node.addPropertyResolver("webdavUrl", this.resolverWebdavUrl); - node.addPropertyResolver("cifsPath", this.resolverCifsPath); - node.addPropertyResolver("fileType16", this.resolverFileType16); - node.addPropertyResolver("fileType32", this.resolverFileType32); - node.addPropertyResolver("size", this.resolverSize); - } - - - // ------------------------------------------------------------------------------ - // IContextListener implementation - - /** - * @see org.alfresco.web.app.context.IContextListener#contextUpdated() - */ - public void contextUpdated() - { - invalidateComponents(); - } - - - // ------------------------------------------------------------------------------ - // NodeEventListener listeners - - /** - * Add a listener to those called by the BrowseBean when nodes are created - */ - public void addNodeEventListener(NodeEventListener listener) - { - getNodeEventListeners().add(listener); - } - - /** - * Remove a listener from the list of those called by BrowseBean - */ - public void removeNodeEventListener(NodeEventListener listener) - { - getNodeEventListeners().remove(listener); - } - - - // ------------------------------------------------------------------------------ - // Navigation action event handlers - - /** - * Change the current view mode based on user selection - * - * @param event ActionEvent - */ - public void viewModeChanged(ActionEvent event) - { - UIModeList viewList = (UIModeList)event.getComponent(); - - // get the view mode ID - String viewMode = viewList.getValue().toString(); - - if (VIEWMODE_DASHBOARD.equals(viewMode) == false) - { - // set the page size based on the style of display - int pageSize = this.viewsConfig.getDefaultPageSize(PAGE_NAME_BROWSE, viewMode); - setPageSizeContent(pageSize); - setPageSizeSpaces(pageSize); - - if (logger.isDebugEnabled()) - logger.debug("Browse view page size set to: " + pageSize); - - setDashboardView(false); - - // push the view mode into the lists - setBrowseViewMode(viewMode); - - navigateBrowseScreen(); - } - else - { - // special case for Dashboard view - setDashboardView(true); - } - } - - - // ------------------------------------------------------------------------------ - // Helper methods - - /** - * Query a list of nodes for the specified parent node Id - * - * @param parentNodeId Id of the parent node or null for the root node - */ - private void queryBrowseNodes(String parentNodeId) - { - long startTime = 0; - if (logger.isDebugEnabled()) - startTime = System.currentTimeMillis(); - - UserTransaction tx = null; - try - { - FacesContext context = FacesContext.getCurrentInstance(); - tx = Repository.getUserTransaction(context, true); - tx.begin(); - - NodeRef parentRef; - if (parentNodeId == null) - { - // no specific parent node specified - use the root node - parentRef = this.nodeService.getRootNode(Repository.getStoreRef()); - } - else - { - // build a NodeRef for the specified Id and our store - parentRef = new NodeRef(Repository.getStoreRef(), parentNodeId); - } - - List childRefs = this.nodeService.getChildAssocs(parentRef, - ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL); - this.containerNodes = new ArrayList(childRefs.size()); - this.contentNodes = new ArrayList(childRefs.size()); - for (ChildAssociationRef ref: childRefs) - { - // create our Node representation from the NodeRef - NodeRef nodeRef = ref.getChildRef(); - - if (this.nodeService.exists(nodeRef)) - { - // find it's type so we can see if it's a node we are interested in - QName type = this.nodeService.getType(nodeRef); - - // make sure the type is defined in the data dictionary - TypeDefinition typeDef = this.dictionaryService.getType(type); - - if (typeDef != null) - { - MapNode node = null; - - // look for Space folder node - if (this.dictionaryService.isSubClass(type, ContentModel.TYPE_FOLDER) == true && - this.dictionaryService.isSubClass(type, ContentModel.TYPE_SYSTEM_FOLDER) == false) - { - // create our Node representation - node = new MapNode(nodeRef, this.nodeService, true); - node.addPropertyResolver("icon", this.resolverSpaceIcon); - node.addPropertyResolver("smallIcon", this.resolverSmallIcon); - - this.containerNodes.add(node); - } - // look for File content node - else if (this.dictionaryService.isSubClass(type, ContentModel.TYPE_CONTENT)) - { - // create our Node representation - node = new MapNode(nodeRef, this.nodeService, true); - setupCommonBindingProperties(node); - - this.contentNodes.add(node); - } - // look for File Link object node - else if (ContentModel.TYPE_FILELINK.equals(type)) - { - // create our File Link Node representation - node = new MapNode(nodeRef, this.nodeService, true); - node.addPropertyResolver("url", this.resolverLinkUrl); - node.addPropertyResolver("webdavUrl", this.resolverLinkWebdavUrl); - node.addPropertyResolver("cifsPath", this.resolverLinkCifsPath); - node.addPropertyResolver("fileType16", this.resolverFileType16); - node.addPropertyResolver("fileType32", this.resolverFileType32); - node.addPropertyResolver("size", this.resolverSize); - - this.contentNodes.add(node); - } - else if (ContentModel.TYPE_FOLDERLINK.equals(type)) - { - // create our Folder Link Node representation - node = new MapNode(nodeRef, this.nodeService, true); - node.addPropertyResolver("icon", this.resolverSpaceIcon); - node.addPropertyResolver("smallIcon", this.resolverSmallIcon); - - this.containerNodes.add(node); - } - - // inform any listeners that a Node wrapper has been created - if (node != null) - { - for (NodeEventListener listener : getNodeEventListeners()) - { - listener.created(node, type); - } - } - } - else - { - if (logger.isEnabledFor(Priority.WARN)) - logger.warn("Found invalid object in database: id = " + nodeRef + ", type = " + type); - } - } - } - - // commit the transaction - tx.commit(); - } - catch (InvalidNodeRefException refErr) - { - Utils.addErrorMessage(MessageFormat.format(Application.getMessage( - FacesContext.getCurrentInstance(), Repository.ERROR_NODEREF), new Object[] {refErr.getNodeRef()}) ); - this.containerNodes = Collections.emptyList(); - this.contentNodes = Collections.emptyList(); - try { if (tx != null) {tx.rollback();} } catch (Exception tex) {} - } - catch (Throwable err) - { - Utils.addErrorMessage(MessageFormat.format(Application.getMessage( - FacesContext.getCurrentInstance(), Repository.ERROR_GENERIC), err.getMessage()), err); - this.containerNodes = Collections.emptyList(); - this.contentNodes = Collections.emptyList(); - try { if (tx != null) {tx.rollback();} } catch (Exception tex) {} - } - - if (logger.isDebugEnabled()) - { - long endTime = System.currentTimeMillis(); - logger.debug("Time to query and build map nodes: " + (endTime - startTime) + "ms"); - } - } - - /** - * Search for a list of nodes using the specific search context - * - * @param searchContext To use to perform the search - */ - private void searchBrowseNodes(SearchContext searchContext) - { - long startTime = 0; - if (logger.isDebugEnabled()) - startTime = System.currentTimeMillis(); - - // get the searcher object to build the query - String query = searchContext.buildQuery(getMinimumSearchLength()); - if (query == null) - { - // failed to build a valid query, the user probably did not enter the - // minimum text required to construct a valid search - Utils.addErrorMessage(MessageFormat.format(Application.getMessage(FacesContext.getCurrentInstance(), MSG_SEARCH_MINIMUM), - new Object[] {getMinimumSearchLength()})); - this.containerNodes = Collections.emptyList(); - this.contentNodes = Collections.emptyList(); - return; - } - - // perform the search against the repo - UserTransaction tx = null; - ResultSet results = null; - try - { - tx = Repository.getUserTransaction(FacesContext.getCurrentInstance(), true); - tx.begin(); - - // Limit search to the first 100 matches - SearchParameters sp = new SearchParameters(); - sp.setLanguage(SearchService.LANGUAGE_LUCENE); - sp.setQuery(query); - sp.addStore(Repository.getStoreRef()); - - int searchLimit = Application.getClientConfig(FacesContext.getCurrentInstance()).getSearchMaxResults(); - if(searchLimit > 0) - { - sp.setLimitBy(LimitBy.FINAL_SIZE); - sp.setLimit(searchLimit); - } - - results = this.searchService.query(sp); - if (logger.isDebugEnabled()) - logger.debug("Search results returned: " + results.length()); - - // create a list of items from the results - this.containerNodes = new ArrayList(results.length()); - this.contentNodes = new ArrayList(results.length()); - if (results.length() != 0) - { - for (ResultSetRow row: results) - { - NodeRef nodeRef = row.getNodeRef(); - - if (this.nodeService.exists(nodeRef)) - { - // find it's type so we can see if it's a node we are interested in - QName type = this.nodeService.getType(nodeRef); - - // make sure the type is defined in the data dictionary - TypeDefinition typeDef = this.dictionaryService.getType(type); - - if (typeDef != null) - { - MapNode node = null; - - // look for Space or File nodes - if (this.dictionaryService.isSubClass(type, ContentModel.TYPE_FOLDER) && - this.dictionaryService.isSubClass(type, ContentModel.TYPE_SYSTEM_FOLDER) == false) - { - // create our Node representation - node = new MapNode(nodeRef, this.nodeService, false); - - node.addPropertyResolver("path", this.resolverPath); - node.addPropertyResolver("displayPath", this.resolverDisplayPath); - node.addPropertyResolver("icon", this.resolverSpaceIcon); - node.addPropertyResolver("smallIcon", this.resolverSmallIcon); - - this.containerNodes.add(node); - } - else if (this.dictionaryService.isSubClass(type, ContentModel.TYPE_CONTENT)) - { - // create our Node representation - node = new MapNode(nodeRef, this.nodeService, false); - - setupCommonBindingProperties(node); - - node.addPropertyResolver("path", this.resolverPath); - node.addPropertyResolver("displayPath", this.resolverDisplayPath); - - this.contentNodes.add(node); - } - // look for File Link object node - else if (ContentModel.TYPE_FILELINK.equals(type)) - { - // create our File Link Node representation - node = new MapNode(nodeRef, this.nodeService, false); - node.addPropertyResolver("url", this.resolverLinkUrl); - node.addPropertyResolver("webdavUrl", this.resolverLinkWebdavUrl); - node.addPropertyResolver("cifsPath", this.resolverLinkCifsPath); - node.addPropertyResolver("fileType16", this.resolverFileType16); - node.addPropertyResolver("fileType32", this.resolverFileType32); - node.addPropertyResolver("size", this.resolverSize); - node.addPropertyResolver("path", this.resolverPath); - node.addPropertyResolver("displayPath", this.resolverDisplayPath); - - this.contentNodes.add(node); - } - else if (ContentModel.TYPE_FOLDERLINK.equals(type)) - { - // create our Folder Link Node representation - node = new MapNode(nodeRef, this.nodeService, false); - node.addPropertyResolver("icon", this.resolverSpaceIcon); - node.addPropertyResolver("smallIcon", this.resolverSmallIcon); - node.addPropertyResolver("path", this.resolverPath); - node.addPropertyResolver("displayPath", this.resolverDisplayPath); - - this.containerNodes.add(node); - } - - // inform any listeners that a Node wrapper has been created - if (node != null) - { - for (NodeEventListener listener : getNodeEventListeners()) - { - listener.created(node, type); - } - } - } - else - { - if (logger.isEnabledFor(Priority.WARN)) - logger.warn("Found invalid object in database: id = " + nodeRef + ", type = " + type); - } - } - else - { - if (logger.isEnabledFor(Priority.WARN)) - logger.warn("Missing object returned from search indexes: id = " + nodeRef + " search query: " + query); - } - } - } - - // commit the transaction - tx.commit(); - } - catch (InvalidNodeRefException refErr) - { - Utils.addErrorMessage(MessageFormat.format(Application.getMessage( - FacesContext.getCurrentInstance(), Repository.ERROR_NODEREF), new Object[] {refErr.getNodeRef()}) ); - this.containerNodes = Collections.emptyList(); - this.contentNodes = Collections.emptyList(); - try { if (tx != null) {tx.rollback();} } catch (Exception tex) {} - } - catch (Throwable err) - { - logger.info("Search failed for: " + query); - Utils.addErrorMessage(MessageFormat.format(Application.getMessage( - FacesContext.getCurrentInstance(), Repository.ERROR_SEARCH), new Object[] {err.getMessage()}), err ); - this.containerNodes = Collections.emptyList(); - this.contentNodes = Collections.emptyList(); - try { if (tx != null) {tx.rollback();} } catch (Exception tex) {} - } - finally - { - if (results != null) - { - results.close(); - } - } - - if (logger.isDebugEnabled()) - { - long endTime = System.currentTimeMillis(); - logger.debug("Time to query and build map nodes: " + (endTime - startTime) + "ms"); - } - } - - - // ------------------------------------------------------------------------------ - // Property Resolvers - - public NodePropertyResolver resolverDownload = new NodePropertyResolver() { - public Object get(Node node) { - return DownloadContentServlet.generateDownloadURL(node.getNodeRef(), node.getName()); - } - }; - - public NodePropertyResolver resolverUrl = new NodePropertyResolver() { - public Object get(Node node) { - return DownloadContentServlet.generateBrowserURL(node.getNodeRef(), node.getName()); - } - }; - - public NodePropertyResolver resolverWebdavUrl = new NodePropertyResolver() { - public Object get(Node node) { - return Utils.generateURL(FacesContext.getCurrentInstance(), node, URLMode.WEBDAV); - } - }; - - public NodePropertyResolver resolverCifsPath = new NodePropertyResolver() { - public Object get(Node node) { - return Utils.generateURL(FacesContext.getCurrentInstance(), node, URLMode.CIFS); - } - }; - - public NodePropertyResolver resolverLinkDownload = new NodePropertyResolver() { - public Object get(Node node) { - NodeRef destRef = (NodeRef)node.getProperties().get(ContentModel.PROP_LINK_DESTINATION); - if (nodeService.exists(destRef) == true) - { - String destName = Repository.getNameForNode(nodeService, destRef); - return DownloadContentServlet.generateDownloadURL(node.getNodeRef(), destName); - } - else - { - // TODO: link object is missing - navigate to a page with appropriate message - return "#"; - } - } - }; - - public NodePropertyResolver resolverLinkUrl = new NodePropertyResolver() { - public Object get(Node node) { - NodeRef destRef = (NodeRef)node.getProperties().get(ContentModel.PROP_LINK_DESTINATION); - if (nodeService.exists(destRef) == true) - { - String destName = Repository.getNameForNode(nodeService, destRef); - return DownloadContentServlet.generateBrowserURL(destRef, destName); - } - else - { - // TODO: link object is missing - navigate to a page with appropriate message - return "#"; - } - } - }; - - public NodePropertyResolver resolverLinkWebdavUrl = new NodePropertyResolver() { - public Object get(Node node) { - NodeRef destRef = (NodeRef)node.getProperties().get(ContentModel.PROP_LINK_DESTINATION); - if (nodeService.exists(destRef) == true) - { - return Utils.generateURL(FacesContext.getCurrentInstance(), new Node(destRef), URLMode.WEBDAV); - } - else - { - // TODO: link object is missing - navigate to a page with appropriate message - return "#"; - } - } - }; - - public NodePropertyResolver resolverLinkCifsPath = new NodePropertyResolver() { - public Object get(Node node) { - NodeRef destRef = (NodeRef)node.getProperties().get(ContentModel.PROP_LINK_DESTINATION); - if (nodeService.exists(destRef) == true) - { - return Utils.generateURL(FacesContext.getCurrentInstance(), new Node(destRef), URLMode.CIFS); - } - else - { - // TODO: link object is missing - navigate to a page with appropriate message - return "#"; - } - } - }; - - public NodePropertyResolver resolverFileType16 = new NodePropertyResolver() { - public Object get(Node node) { - return Utils.getFileTypeImage(node.getName(), true); - } - }; - - public NodePropertyResolver resolverFileType32 = new NodePropertyResolver() { - public Object get(Node node) { - return Utils.getFileTypeImage(node.getName(), false); - } - }; - - public NodePropertyResolver resolverPath = new NodePropertyResolver() { - public Object get(Node node) { - return nodeService.getPath(node.getNodeRef()); - } - }; - - public NodePropertyResolver resolverDisplayPath = new NodePropertyResolver() { - public Object get(Node node) { - // TODO: replace this with a method that shows the full display name - not QNames? - return Repository.getDisplayPath( (Path)node.getProperties().get("path") ); - } - }; - - public NodePropertyResolver resolverSpaceIcon = new NodePropertyResolver() { - public Object get(Node node) { - QNameNodeMap props = (QNameNodeMap)node.getProperties(); - String icon = (String)props.getRaw("app:icon"); - return (icon != null ? icon : CreateSpaceWizard.DEFAULT_SPACE_ICON_NAME); - } - }; - - public NodePropertyResolver resolverSmallIcon = new NodePropertyResolver() { - public Object get(Node node) { - QNameNodeMap props = (QNameNodeMap)node.getProperties(); - String icon = (String)props.getRaw("app:icon"); - return (icon != null ? icon + "-16" : SPACE_SMALL_DEFAULT); - } - }; - - public NodePropertyResolver resolverMimetype = new NodePropertyResolver() { - public Object get(Node node) { - ContentData content = (ContentData)node.getProperties().get(ContentModel.PROP_CONTENT); - return (content != null ? content.getMimetype() : null); - } - }; - - public NodePropertyResolver resolverSize = new NodePropertyResolver() { - public Object get(Node node) { - ContentData content = (ContentData)node.getProperties().get(ContentModel.PROP_CONTENT); - return (content != null ? new Long(content.getSize()) : 0L); - } - }; - - - // ------------------------------------------------------------------------------ - // Navigation action event handlers - - /** - * Action called from the Simple Search component. - * Sets up the SearchContext object with the values from the simple search menu. - */ - public void search(ActionEvent event) - { - // setup the search text string on the top-level navigation handler - UISimpleSearch search = (UISimpleSearch)event.getComponent(); - this.navigator.setSearchContext(search.getSearchContext()); - - navigateBrowseScreen(); - } - - /** - * Action called to Close the search dialog by returning to the last view node Id - */ - public void closeSearch(ActionEvent event) - { - // set the current node Id ready for page refresh - this.navigator.setCurrentNodeId( this.navigator.getCurrentNodeId() ); - } - - /** - * Update page size based on user selection - */ - public void updateSpacesPageSize(ActionEvent event) - { - try - { - int size = Integer.parseInt(this.pageSizeSpacesStr); - if (size >= 0) - { - this.pageSizeSpaces = size; - } - else - { - // reset to known value if this occurs - this.pageSizeSpacesStr = Integer.toString(this.pageSizeSpaces); - } - } - catch (NumberFormatException err) - { - // reset to known value if this occurs - this.pageSizeSpacesStr = Integer.toString(this.pageSizeSpaces); - } - } - - /** - * Update page size based on user selection - */ - public void updateContentPageSize(ActionEvent event) - { - try - { - int size = Integer.parseInt(this.pageSizeContentStr); - if (size >= 0) - { - this.pageSizeContent = size; - } - else - { - // reset to known value if this occurs - this.pageSizeContentStr = Integer.toString(this.pageSizeContent); - } - } - catch (NumberFormatException err) - { - // reset to known value if this occurs - this.pageSizeContentStr = Integer.toString(this.pageSizeContent); - } - } - - /** - * Action called when a folder space is clicked. - * Navigate into the space. - */ - public void clickSpace(ActionEvent event) - { - UIActionLink link = (UIActionLink)event.getComponent(); - Map params = link.getParameterMap(); - String id = params.get("id"); - if (id != null && id.length() != 0) - { - try - { - NodeRef ref = new NodeRef(Repository.getStoreRef(), id); - - // handle special folder link node case - if (ContentModel.TYPE_FOLDERLINK.equals(this.nodeService.getType(ref))) - { - ref = (NodeRef)this.nodeService.getProperty(ref, ContentModel.PROP_LINK_DESTINATION); - } - - clickSpace(ref); - } - catch (InvalidNodeRefException refErr) - { - Utils.addErrorMessage(MessageFormat.format(Application.getMessage( - FacesContext.getCurrentInstance(), Repository.ERROR_NODEREF), new Object[] {id}) ); - } - } - } - - /** - * Action called when a folder space is clicked. - * - * @param nodeRef The node being clicked - */ - public void clickSpace(NodeRef nodeRef) - { - // refresh UI based on node selection - updateUILocation(nodeRef); - } - - /** - * Handler called when a path element is clicked - navigate to the appropriate Space - */ - public void clickSpacePath(ActionEvent event) - { - UINodePath.PathElementEvent pathEvent = (UINodePath.PathElementEvent)event; - NodeRef ref = pathEvent.NodeReference; - try - { - // refresh UI based on node selection - this.updateUILocation(ref); - } - catch (InvalidNodeRefException refErr) - { - Utils.addErrorMessage(MessageFormat.format(Application.getMessage( - FacesContext.getCurrentInstance(), Repository.ERROR_NODEREF), new Object[] {ref.getId()}) ); - } - } - - /** - * Action called when a folders direct descendant (in the 'list' browse mode) is clicked. - * Navigate into the the descendant space. - */ - public void clickDescendantSpace(ActionEvent event) - { - UINodeDescendants.NodeSelectedEvent nodeEvent = (UINodeDescendants.NodeSelectedEvent)event; - NodeRef nodeRef = nodeEvent.NodeReference; - if (nodeRef == null) - { - throw new IllegalStateException("NodeRef returned from UINodeDescendants.NodeSelectedEvent cannot be null!"); - } - - if (logger.isDebugEnabled()) - logger.debug("Selected noderef Id: " + nodeRef.getId()); - - try - { - // user can either select a descendant of a node display on the page which means we - // must add the it's parent and itself to the breadcrumb - ChildAssociationRef parentAssocRef = nodeService.getPrimaryParent(nodeRef); - - if (logger.isDebugEnabled()) - { - logger.debug("Selected item getPrimaryParent().getChildRef() noderef Id: " + parentAssocRef.getChildRef().getId()); - logger.debug("Selected item getPrimaryParent().getParentRef() noderef Id: " + parentAssocRef.getParentRef().getId()); - logger.debug("Current value getNavigator().getCurrentNodeId() noderef Id: " + this.navigator.getCurrentNodeId()); - } - - if (nodeEvent.IsParent == false) - { - // a descendant of the displayed node was selected - // first refresh based on the parent and add to the breadcrumb - updateUILocation(parentAssocRef.getParentRef()); - - // now add our selected node - updateUILocation(nodeRef); - } - else - { - // else the parent ellipses i.e. the displayed node was selected - updateUILocation(nodeRef); - } - } - catch (InvalidNodeRefException refErr) - { - Utils.addErrorMessage(MessageFormat.format(Application.getMessage( - FacesContext.getCurrentInstance(), Repository.ERROR_NODEREF), new Object[] {nodeRef.getId()}) ); - } - } - - /** - * Action event called by all Browse actions that need to setup a Space context - * before an action page/wizard is called. The context will be a Node in setActionSpace() which - * can be retrieved on the action page from BrowseBean.getActionSpace(). - * - * @param event ActionEvent - */ - public void setupSpaceAction(ActionEvent event) - { - UIActionLink link = (UIActionLink)event.getComponent(); - Map params = link.getParameterMap(); - String id = params.get("id"); - setupSpaceAction(id, true); - } - - /** - * Public helper to setup action pages with Space context - * - * @param id of the Space node to setup context for - */ - public void setupSpaceAction(String id, boolean invalidate) - { - if (id != null && id.length() != 0) - { - if (logger.isDebugEnabled()) - logger.debug("Setup for action, setting current space to: " + id); - - try - { - // create the node ref, then our node representation - NodeRef ref = new NodeRef(Repository.getStoreRef(), id); - Node node = new Node(ref); - - // resolve icon in-case one has not been set - node.addPropertyResolver("icon", this.resolverSpaceIcon); - - // prepare a node for the action context - setActionSpace(node); - - // setup the dispatch context in case it is required - this.navigator.setupDispatchContext(node); - } - catch (InvalidNodeRefException refErr) - { - Utils.addErrorMessage(MessageFormat.format(Application.getMessage( - FacesContext.getCurrentInstance(), Repository.ERROR_NODEREF), new Object[] {id}) ); - } - } - else - { - setActionSpace(null); - } - - // clear the UI state in preparation for finishing the next action - if (invalidate == true) - { - // use the context service to notify all registered beans - UIContextService.getInstance(FacesContext.getCurrentInstance()).notifyBeans(); - } - } - - /** - * Acrtion event called by Delete Space actions. We setup the action space as normal, then prepare - * any special case message string to be shown to the user if they are trying to delete specific spaces. - */ - public void setupDeleteAction(ActionEvent event) - { - String message = null; - - setupSpaceAction(event); - - Node node = getActionSpace(); - if (node != null) - { - NodeRef companyRootRef = new NodeRef(Repository.getStoreRef(), Application.getCompanyRootId()); - if (node.getNodeRef().equals(companyRootRef)) - { - message = Application.getMessage(FacesContext.getCurrentInstance(), MSG_DELETE_COMPANYROOT); - } - } - - setDeleteMessage(message); - } - - /** - * Action event called by all actions that need to setup a Content Document context on the - * BrowseBean before an action page/wizard is called. The context will be a Node in - * setDocument() which can be retrieved on the action page from BrowseBean.getDocument(). - */ - public void setupContentAction(ActionEvent event) - { - UIActionLink link = (UIActionLink)event.getComponent(); - Map params = link.getParameterMap(); - setupContentAction(params.get("id"), true); - } - - /** - * Public helper to setup action pages with content context - * - * @param id of the content node to setup context for - */ - public void setupContentAction(String id, boolean invalidate) - { - if (id != null && id.length() != 0) - { - if (logger.isDebugEnabled()) - logger.debug("Setup for action, setting current document to: " + id); - - try - { - // create the node ref, then our node representation - NodeRef ref = new NodeRef(Repository.getStoreRef(), id); - Node node = new Node(ref); - - // store the URL to for downloading the content - if (ContentModel.TYPE_FILELINK.equals(node.getType())) - { - node.addPropertyResolver("url", this.resolverLinkDownload); - } - else - { - node.addPropertyResolver("url", this.resolverDownload); - } - node.addPropertyResolver("fileType32", this.resolverFileType32); - node.addPropertyResolver("mimetype", this.resolverMimetype); - node.addPropertyResolver("size", this.resolverSize); - - for (NodeEventListener listener : getNodeEventListeners()) - { - listener.created(node, node.getType()); - } - - // get hold of the DocumentDetailsBean and reset it - DocumentDetailsBean docDetails = (DocumentDetailsBean)FacesContext.getCurrentInstance(). - getExternalContext().getSessionMap().get("DocumentDetailsBean"); - if (docDetails != null) - { - docDetails.reset(); - } - - // remember the document - setDocument(node); - - // setup the dispatch context in case it is required - this.navigator.setupDispatchContext(node); - } - catch (InvalidNodeRefException refErr) - { - Utils.addErrorMessage(MessageFormat.format(Application.getMessage( - FacesContext.getCurrentInstance(), Repository.ERROR_NODEREF), new Object[] {id}) ); - } - } - else - { - setDocument(null); - } - - // clear the UI state in preparation for finishing the next action - if (invalidate == true) - { - // use the context service to notify all registered beans - UIContextService.getInstance(FacesContext.getCurrentInstance()).notifyBeans(); - } - } - - /** - * Removes the given node from the breadcrumb i.e. following a delete - * - * @param node The space to remove from the breadcrumb - */ - public void removeSpaceFromBreadcrumb(Node node) - { - List location = navigator.getLocation(); - IBreadcrumbHandler handler = location.get(location.size() - 1); - if (handler instanceof BrowseBreadcrumbHandler) - { - // see if the current breadcrumb location is our node - if ( ((BrowseBreadcrumbHandler)handler).getNodeRef().equals(node.getNodeRef()) == true ) - { - location.remove(location.size() - 1); - - // now work out which node to set the list to refresh against - if (location.size() != 0) - { - handler = location.get(location.size() - 1); - if (handler instanceof BrowseBreadcrumbHandler) - { - // change the current node Id - navigator.setCurrentNodeId(((BrowseBreadcrumbHandler)handler).getNodeRef().getId()); - } - else - { - // TODO: shouldn't do this - but for now the user home dir is the root! - navigator.setCurrentNodeId(Application.getCurrentUser(FacesContext.getCurrentInstance()).getHomeSpaceId()); - } - } - } - } - } - - /** - * Support for refresh of lists via special case for an External Access URL. - * these URLs restart the JSF lifecycle but an old UIRichList is restored from - * the component tree - which needs clearing "late" in the lifecycle process. - */ - public void externalAccessRefresh() - { - this.externalForceRefresh = true; - } - - - // ------------------------------------------------------------------------------ - // Private helpers - - /** - * Initialise default values from client configuration - */ - private void initFromClientConfig() - { - ConfigService config = Application.getConfigService(FacesContext.getCurrentInstance()); - - this.viewsConfig = (ViewsConfigElement)config.getConfig("Views"). - getConfigElement(ViewsConfigElement.CONFIG_ELEMENT_ID); - - this.browseViewMode = this.viewsConfig.getDefaultView(PAGE_NAME_BROWSE); - int pageSize = this.viewsConfig.getDefaultPageSize(PAGE_NAME_BROWSE, this.browseViewMode); - setPageSizeContent(pageSize); - setPageSizeSpaces(pageSize); - } - - /** - * @return the Set of NodeEventListeners registered against this bean - */ - private Set getNodeEventListeners() - { - if (this.nodeEventListeners == null) - { - this.nodeEventListeners = new HashSet(); - - FacesContext fc = FacesContext.getCurrentInstance(); - - Config listenerConfig = Application.getConfigService(fc).getConfig("Node Event Listeners"); - if (listenerConfig != null) - { - ConfigElement listenerElement = listenerConfig.getConfigElement("node-event-listeners"); - if (listenerElement != null) - { - for (ConfigElement child : listenerElement.getChildren()) - { - if (child.getName().equals("listener")) - { - // retrieved the JSF Managed Bean identified in the config - String listenerName = child.getValue().trim(); - Object bean = FacesHelper.getManagedBean(fc, listenerName); - if (bean instanceof NodeEventListener) - { - addNodeEventListener((NodeEventListener)bean); - } - } - } - } - } - } - return this.nodeEventListeners; - } - - /** - * Refresh the UI after a Space selection change. Adds the selected space to the breadcrumb - * location path and also updates the list components in the UI. - * - * @param ref NodeRef of the selected space - */ - public void updateUILocation(NodeRef ref) - { - // get the current breadcrumb location and append a new handler to it - // our handler know the ID of the selected node and the display label for it - List location = this.navigator.getLocation(); - if (location.size() != 0) - { - // attempt to find the ID - if it's already in the breadcrumb then we - // navigate directly to that node - rather than add duplication to the breadcrumb path - boolean foundNode = false; - for (int i=0; i newLocation = new ArrayList(i+1); - //newLocation.addAll(location.subList(0, i + 1)); - //this.navigator.setLocation(newLocation); - // TODO: but instead for now we do this: - int count = location.size(); - for (int n=i+1; n nodeEventListeners = null; - - /** Component references */ - protected UIRichList spacesRichList; - protected UIRichList contentRichList; - private UIStatusMessage statusMessage; - - /** Transient lists of container and content nodes for display */ - private List containerNodes = null; - private List contentNodes = null; - - /** The current space and it's properties - if any */ - private Node actionSpace; - - /** The current document */ - private Node document; - - /** Special message to display when user deleting certain folders e.g. Company Home */ - private String deleteMessage; - - /** The current browse view mode - set to a well known IRichListRenderer identifier */ - private String browseViewMode; - - /** The current browse view page sizes */ - private int pageSizeSpaces; - private int pageSizeContent; - private String pageSizeSpacesStr; - private String pageSizeContentStr; - - /** True if current space has a dashboard (template) view available */ - private boolean dashboardView; - - private boolean externalForceRefresh = false; -} +/* + * Copyright (C) 2005 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ +package org.alfresco.web.bean; + +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.faces.application.FacesMessage; +import javax.faces.context.FacesContext; +import javax.faces.event.ActionEvent; +import javax.transaction.UserTransaction; + +import org.alfresco.config.Config; +import org.alfresco.config.ConfigElement; +import org.alfresco.config.ConfigService; +import org.alfresco.model.ContentModel; +import org.alfresco.service.cmr.dictionary.DictionaryService; +import org.alfresco.service.cmr.dictionary.TypeDefinition; +import org.alfresco.service.cmr.lock.LockService; +import org.alfresco.service.cmr.model.FileFolderService; +import org.alfresco.service.cmr.repository.ChildAssociationRef; +import org.alfresco.service.cmr.repository.ContentData; +import org.alfresco.service.cmr.repository.InvalidNodeRefException; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.cmr.repository.Path; +import org.alfresco.service.cmr.search.LimitBy; +import org.alfresco.service.cmr.search.ResultSet; +import org.alfresco.service.cmr.search.ResultSetRow; +import org.alfresco.service.cmr.search.SearchParameters; +import org.alfresco.service.cmr.search.SearchService; +import org.alfresco.service.namespace.QName; +import org.alfresco.service.namespace.RegexQNamePattern; +import org.alfresco.web.app.AlfrescoNavigationHandler; +import org.alfresco.web.app.Application; +import org.alfresco.web.app.context.IContextListener; +import org.alfresco.web.app.context.UIContextService; +import org.alfresco.web.app.servlet.DownloadContentServlet; +import org.alfresco.web.app.servlet.FacesHelper; +import org.alfresco.web.bean.repository.MapNode; +import org.alfresco.web.bean.repository.Node; +import org.alfresco.web.bean.repository.NodePropertyResolver; +import org.alfresco.web.bean.repository.QNameNodeMap; +import org.alfresco.web.bean.repository.Repository; +import org.alfresco.web.bean.spaces.CreateSpaceWizard; +import org.alfresco.web.config.ViewsConfigElement; +import org.alfresco.web.ui.common.Utils; +import org.alfresco.web.ui.common.Utils.URLMode; +import org.alfresco.web.ui.common.component.IBreadcrumbHandler; +import org.alfresco.web.ui.common.component.UIActionLink; +import org.alfresco.web.ui.common.component.UIBreadcrumb; +import org.alfresco.web.ui.common.component.UIModeList; +import org.alfresco.web.ui.common.component.UIStatusMessage; +import org.alfresco.web.ui.common.component.UIPanel.ExpandedEvent; +import org.alfresco.web.ui.common.component.data.UIRichList; +import org.alfresco.web.ui.repo.component.IRepoBreadcrumbHandler; +import org.alfresco.web.ui.repo.component.UINodeDescendants; +import org.alfresco.web.ui.repo.component.UINodePath; +import org.alfresco.web.ui.repo.component.UISimpleSearch; +import org.apache.log4j.Logger; +import org.apache.log4j.Priority; + +/** + * Bean providing properties and behaviour for the main folder/document browse screen and + * search results screens. + * + * @author Kevin Roast + */ +public class BrowseBean implements IContextListener +{ + // ------------------------------------------------------------------------------ + // Construction + + /** + * Default Constructor + */ + public BrowseBean() + { + UIContextService.getInstance(FacesContext.getCurrentInstance()).registerBean(this); + + initFromClientConfig(); + } + + + // ------------------------------------------------------------------------------ + // Bean property getters and setters + + /** + * @param nodeService The NodeService to set. + */ + public void setNodeService(NodeService nodeService) + { + this.nodeService = nodeService; + } + + /** + * @param searchService The Searcher to set. + */ + public void setSearchService(SearchService searchService) + { + this.searchService = searchService; + } + + /** + * @param lockService The Lock Service to set. + */ + public void setLockService(LockService lockService) + { + this.lockService = lockService; + } + + /** + * @param navigator The NavigationBean to set. + */ + public void setNavigator(NavigationBean navigator) + { + this.navigator = navigator; + } + + /** + * @param dictionaryService The DictionaryService to set. + */ + public void setDictionaryService(DictionaryService dictionaryService) + { + this.dictionaryService = dictionaryService; + } + + /** + * @param fileFolderService The FileFolderService to set. + */ + public void setFileFolderService(FileFolderService fileFolderService) + { + this.fileFolderService = fileFolderService; + } + + /** + * @return Returns the browse View mode. See UIRichList + */ + public String getBrowseViewMode() + { + return this.browseViewMode; + } + + /** + * @param browseViewMode The browse View mode to set. See UIRichList. + */ + public void setBrowseViewMode(String browseViewMode) + { + this.browseViewMode = browseViewMode; + } + + /** + * @return Returns true if dashboard view is available for the current node. + */ + public boolean isDashboardView() + { + return this.dashboardView; + } + + /** + * @param dashboardView The dashboard view mode to set. + */ + public void setDashboardView(boolean dashboardView) + { + this.dashboardView = dashboardView; + if (dashboardView == true) + { + FacesContext fc = FacesContext.getCurrentInstance(); + fc.getApplication().getNavigationHandler().handleNavigation(fc, null, "dashboard"); + } + } + + public int getPageSizeContent() + { + return this.pageSizeContent; + } + + public void setPageSizeContent(int pageSizeContent) + { + this.pageSizeContent = pageSizeContent; + this.pageSizeContentStr = Integer.toString(pageSizeContent); + } + + public int getPageSizeSpaces() + { + return this.pageSizeSpaces; + } + + public void setPageSizeSpaces(int pageSizeSpaces) + { + this.pageSizeSpaces = pageSizeSpaces; + this.pageSizeSpacesStr = Integer.toString(pageSizeSpaces); + } + + public String getPageSizeContentStr() + { + return this.pageSizeContentStr; + } + + public void setPageSizeContentStr(String pageSizeContentStr) + { + this.pageSizeContentStr = pageSizeContentStr; + } + + public String getPageSizeSpacesStr() + { + return this.pageSizeSpacesStr; + } + + public void setPageSizeSpacesStr(String pageSizeSpacesStr) + { + this.pageSizeSpacesStr = pageSizeSpacesStr; + } + + /** + * @return Returns the minimum length of a valid search string. + */ + public int getMinimumSearchLength() + { + return Application.getClientConfig(FacesContext.getCurrentInstance()). + getSearchMinimum(); + } + + /** + * @return Returns the panels expanded state map. + */ + public Map getPanels() + { + return this.panels; + } + + /** + * @param panels The panels expanded state map. + */ + public void setPanels(Map panels) + { + this.panels = panels; + } + + /** + * @return Returns the Space Node being used for the current browse screen action. + */ + public Node getActionSpace() + { + return this.actionSpace; + } + + /** + * @param actionSpace Set the Space Node to be used for the current browse screen action. + */ + public void setActionSpace(Node actionSpace) + { + if (actionSpace != null) + { + for (NodeEventListener listener : getNodeEventListeners()) + { + listener.created(actionSpace, actionSpace.getType()); + } + } + this.actionSpace = actionSpace; + } + + /** + * @return The document node being used for the current operation + */ + public Node getDocument() + { + return this.document; + } + + /** + * @param document The document node to be used for the current operation + */ + public void setDocument(Node document) + { + if (document != null) + { + for (NodeEventListener listener : getNodeEventListeners()) + { + listener.created(document, document.getType()); + } + } + this.document = document; + } + + /** + * @param contentRichList The contentRichList to set. + */ + public void setContentRichList(UIRichList browseRichList) + { + this.contentRichList = browseRichList; + if (this.contentRichList != null) + { + this.contentRichList.setInitialSortColumn( + this.viewsConfig.getDefaultSortColumn(PAGE_NAME_BROWSE)); + this.contentRichList.setInitialSortDescending( + this.viewsConfig.hasDescendingSort(PAGE_NAME_BROWSE)); + } + // special case to handle an External Access URL + // these URLs restart the JSF lifecycle but an old UIRichList is restored from + // the component tree - which needs clearing "late" in the lifecycle process + if (externalForceRefresh) + { + this.contentRichList.setValue(null); + externalForceRefresh = false; + } + } + + /** + * @return Returns the contentRichList. + */ + public UIRichList getContentRichList() + { + return this.contentRichList; + } + + /** + * @param spacesRichList The spacesRichList to set. + */ + public void setSpacesRichList(UIRichList detailsRichList) + { + this.spacesRichList = detailsRichList; + if (this.spacesRichList != null) + { + // set the initial sort column and direction + this.spacesRichList.setInitialSortColumn( + this.viewsConfig.getDefaultSortColumn(PAGE_NAME_BROWSE)); + this.spacesRichList.setInitialSortDescending( + this.viewsConfig.hasDescendingSort(PAGE_NAME_BROWSE)); + } + if (externalForceRefresh) + { + this.spacesRichList.setValue(null); + } + } + + /** + * @return Returns the spacesRichList. + */ + public UIRichList getSpacesRichList() + { + return this.spacesRichList; + } + + /** + * @return Returns the statusMessage component. + */ + public UIStatusMessage getStatusMessage() + { + return this.statusMessage; + } + + /** + * @param statusMessage The statusMessage component to set. + */ + public void setStatusMessage(UIStatusMessage statusMessage) + { + this.statusMessage = statusMessage; + } + + /** + * @return Returns the deleteMessage. + */ + public String getDeleteMessage() + { + return this.deleteMessage; + } + + /** + * @param deleteMessage The deleteMessage to set. + */ + public void setDeleteMessage(String deleteMessage) + { + this.deleteMessage = deleteMessage; + } + + /** + * Page accessed bean method to get the container nodes currently being browsed + * + * @return List of container Node objects for the current browse location + */ + public List getNodes() + { + // the references to container nodes and content nodes are transient for one use only + // we do this so we only query/search once - as we cannot distinguish between node types + // until after the query. The logic is a bit confusing but otherwise we would need to + // perform the same query or search twice for every screen refresh. + if (this.containerNodes == null) + { + if (this.navigator.getSearchContext() == null) + { + queryBrowseNodes(this.navigator.getCurrentNodeId()); + } + else + { + searchBrowseNodes(this.navigator.getSearchContext()); + } + } + List result = this.containerNodes; + + // we clear the member variable during invalidateComponents() + + return result; + } + + /** + * Page accessed bean method to get the content nodes currently being browsed + * + * @return List of content Node objects for the current browse location + */ + public List getContent() + { + // see comment in getNodes() above for reasoning here + if (this.contentNodes == null) + { + if (this.navigator.getSearchContext() == null) + { + queryBrowseNodes(this.navigator.getCurrentNodeId()); + } + else + { + searchBrowseNodes(this.navigator.getSearchContext()); + } + } + List result = this.contentNodes; + + // we clear the member variable during invalidateComponents() + + return result; + } + + /** + * Setup the common properties required at data-binding time. + *

+ * These are properties used by components on the page when iterating over the nodes. + * The properties are available as the Node is a Map so they can be accessed directly + * by name. Information such as download URL, size and filetype are provided etc. + *

+ * We use a set of anonymous inner classes to provide the implemention for the property + * getters. The interfaces are only called when the properties are first requested. + * + * @param node Node to add the properties too + */ + public void setupCommonBindingProperties(Node node) + { + // special properties to be used by the value binding components on the page + node.addPropertyResolver("url", this.resolverUrl); + node.addPropertyResolver("webdavUrl", this.resolverWebdavUrl); + node.addPropertyResolver("cifsPath", this.resolverCifsPath); + node.addPropertyResolver("fileType16", this.resolverFileType16); + node.addPropertyResolver("fileType32", this.resolverFileType32); + node.addPropertyResolver("size", this.resolverSize); + } + + + // ------------------------------------------------------------------------------ + // IContextListener implementation + + /** + * @see org.alfresco.web.app.context.IContextListener#contextUpdated() + */ + public void contextUpdated() + { + invalidateComponents(); + } + + + // ------------------------------------------------------------------------------ + // NodeEventListener listeners + + /** + * Add a listener to those called by the BrowseBean when nodes are created + */ + public void addNodeEventListener(NodeEventListener listener) + { + getNodeEventListeners().add(listener); + } + + /** + * Remove a listener from the list of those called by BrowseBean + */ + public void removeNodeEventListener(NodeEventListener listener) + { + getNodeEventListeners().remove(listener); + } + + + // ------------------------------------------------------------------------------ + // Navigation action event handlers + + /** + * Change the current view mode based on user selection + * + * @param event ActionEvent + */ + public void viewModeChanged(ActionEvent event) + { + UIModeList viewList = (UIModeList)event.getComponent(); + + // get the view mode ID + String viewMode = viewList.getValue().toString(); + + if (VIEWMODE_DASHBOARD.equals(viewMode) == false) + { + // set the page size based on the style of display + int pageSize = this.viewsConfig.getDefaultPageSize(PAGE_NAME_BROWSE, viewMode); + setPageSizeContent(pageSize); + setPageSizeSpaces(pageSize); + + if (logger.isDebugEnabled()) + logger.debug("Browse view page size set to: " + pageSize); + + setDashboardView(false); + + // push the view mode into the lists + setBrowseViewMode(viewMode); + + navigateBrowseScreen(); + } + else + { + // special case for Dashboard view + setDashboardView(true); + } + } + + + // ------------------------------------------------------------------------------ + // Helper methods + + /** + * Query a list of nodes for the specified parent node Id + * + * @param parentNodeId Id of the parent node or null for the root node + */ + private void queryBrowseNodes(String parentNodeId) + { + long startTime = 0; + if (logger.isDebugEnabled()) + startTime = System.currentTimeMillis(); + + UserTransaction tx = null; + try + { + FacesContext context = FacesContext.getCurrentInstance(); + tx = Repository.getUserTransaction(context, true); + tx.begin(); + + NodeRef parentRef; + if (parentNodeId == null) + { + // no specific parent node specified - use the root node + parentRef = this.nodeService.getRootNode(Repository.getStoreRef()); + } + else + { + // build a NodeRef for the specified Id and our store + parentRef = new NodeRef(Repository.getStoreRef(), parentNodeId); + } + + List childRefs = this.nodeService.getChildAssocs(parentRef, + ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL); + this.containerNodes = new ArrayList(childRefs.size()); + this.contentNodes = new ArrayList(childRefs.size()); + for (ChildAssociationRef ref: childRefs) + { + // create our Node representation from the NodeRef + NodeRef nodeRef = ref.getChildRef(); + + if (this.nodeService.exists(nodeRef)) + { + // find it's type so we can see if it's a node we are interested in + QName type = this.nodeService.getType(nodeRef); + + // make sure the type is defined in the data dictionary + TypeDefinition typeDef = this.dictionaryService.getType(type); + + if (typeDef != null) + { + MapNode node = null; + + // look for Space folder node + if (this.dictionaryService.isSubClass(type, ContentModel.TYPE_FOLDER) == true && + this.dictionaryService.isSubClass(type, ContentModel.TYPE_SYSTEM_FOLDER) == false) + { + // create our Node representation + node = new MapNode(nodeRef, this.nodeService, true); + node.addPropertyResolver("icon", this.resolverSpaceIcon); + node.addPropertyResolver("smallIcon", this.resolverSmallIcon); + + this.containerNodes.add(node); + } + // look for File content node + else if (this.dictionaryService.isSubClass(type, ContentModel.TYPE_CONTENT)) + { + // create our Node representation + node = new MapNode(nodeRef, this.nodeService, true); + setupCommonBindingProperties(node); + + this.contentNodes.add(node); + } + // look for File Link object node + else if (ContentModel.TYPE_FILELINK.equals(type)) + { + // create our File Link Node representation + node = new MapNode(nodeRef, this.nodeService, true); + node.addPropertyResolver("url", this.resolverLinkUrl); + node.addPropertyResolver("webdavUrl", this.resolverLinkWebdavUrl); + node.addPropertyResolver("cifsPath", this.resolverLinkCifsPath); + node.addPropertyResolver("fileType16", this.resolverFileType16); + node.addPropertyResolver("fileType32", this.resolverFileType32); + node.addPropertyResolver("size", this.resolverSize); + + this.contentNodes.add(node); + } + else if (ContentModel.TYPE_FOLDERLINK.equals(type)) + { + // create our Folder Link Node representation + node = new MapNode(nodeRef, this.nodeService, true); + node.addPropertyResolver("icon", this.resolverSpaceIcon); + node.addPropertyResolver("smallIcon", this.resolverSmallIcon); + + this.containerNodes.add(node); + } + + // inform any listeners that a Node wrapper has been created + if (node != null) + { + for (NodeEventListener listener : getNodeEventListeners()) + { + listener.created(node, type); + } + } + } + else + { + if (logger.isEnabledFor(Priority.WARN)) + logger.warn("Found invalid object in database: id = " + nodeRef + ", type = " + type); + } + } + } + + // commit the transaction + tx.commit(); + } + catch (InvalidNodeRefException refErr) + { + Utils.addErrorMessage(MessageFormat.format(Application.getMessage( + FacesContext.getCurrentInstance(), Repository.ERROR_NODEREF), new Object[] {refErr.getNodeRef()}) ); + this.containerNodes = Collections.emptyList(); + this.contentNodes = Collections.emptyList(); + try { if (tx != null) {tx.rollback();} } catch (Exception tex) {} + } + catch (Throwable err) + { + Utils.addErrorMessage(MessageFormat.format(Application.getMessage( + FacesContext.getCurrentInstance(), Repository.ERROR_GENERIC), err.getMessage()), err); + this.containerNodes = Collections.emptyList(); + this.contentNodes = Collections.emptyList(); + try { if (tx != null) {tx.rollback();} } catch (Exception tex) {} + } + + if (logger.isDebugEnabled()) + { + long endTime = System.currentTimeMillis(); + logger.debug("Time to query and build map nodes: " + (endTime - startTime) + "ms"); + } + } + + /** + * Search for a list of nodes using the specific search context + * + * @param searchContext To use to perform the search + */ + private void searchBrowseNodes(SearchContext searchContext) + { + long startTime = 0; + if (logger.isDebugEnabled()) + startTime = System.currentTimeMillis(); + + // get the searcher object to build the query + String query = searchContext.buildQuery(getMinimumSearchLength()); + if (query == null) + { + // failed to build a valid query, the user probably did not enter the + // minimum text required to construct a valid search + Utils.addErrorMessage(MessageFormat.format(Application.getMessage(FacesContext.getCurrentInstance(), MSG_SEARCH_MINIMUM), + new Object[] {getMinimumSearchLength()})); + this.containerNodes = Collections.emptyList(); + this.contentNodes = Collections.emptyList(); + return; + } + + // perform the search against the repo + UserTransaction tx = null; + ResultSet results = null; + try + { + tx = Repository.getUserTransaction(FacesContext.getCurrentInstance(), true); + tx.begin(); + + // Limit search to the first 100 matches + SearchParameters sp = new SearchParameters(); + sp.setLanguage(SearchService.LANGUAGE_LUCENE); + sp.setQuery(query); + sp.addStore(Repository.getStoreRef()); + + int searchLimit = Application.getClientConfig(FacesContext.getCurrentInstance()).getSearchMaxResults(); + if(searchLimit > 0) + { + sp.setLimitBy(LimitBy.FINAL_SIZE); + sp.setLimit(searchLimit); + } + + results = this.searchService.query(sp); + if (logger.isDebugEnabled()) + logger.debug("Search results returned: " + results.length()); + + // create a list of items from the results + this.containerNodes = new ArrayList(results.length()); + this.contentNodes = new ArrayList(results.length()); + if (results.length() != 0) + { + for (ResultSetRow row: results) + { + NodeRef nodeRef = row.getNodeRef(); + + if (this.nodeService.exists(nodeRef)) + { + // find it's type so we can see if it's a node we are interested in + QName type = this.nodeService.getType(nodeRef); + + // make sure the type is defined in the data dictionary + TypeDefinition typeDef = this.dictionaryService.getType(type); + + if (typeDef != null) + { + MapNode node = null; + + // look for Space or File nodes + if (this.dictionaryService.isSubClass(type, ContentModel.TYPE_FOLDER) && + this.dictionaryService.isSubClass(type, ContentModel.TYPE_SYSTEM_FOLDER) == false) + { + // create our Node representation + node = new MapNode(nodeRef, this.nodeService, false); + + node.addPropertyResolver("path", this.resolverPath); + node.addPropertyResolver("displayPath", this.resolverDisplayPath); + node.addPropertyResolver("icon", this.resolverSpaceIcon); + node.addPropertyResolver("smallIcon", this.resolverSmallIcon); + + this.containerNodes.add(node); + } + else if (this.dictionaryService.isSubClass(type, ContentModel.TYPE_CONTENT)) + { + // create our Node representation + node = new MapNode(nodeRef, this.nodeService, false); + + setupCommonBindingProperties(node); + + node.addPropertyResolver("path", this.resolverPath); + node.addPropertyResolver("displayPath", this.resolverDisplayPath); + + this.contentNodes.add(node); + } + // look for File Link object node + else if (ContentModel.TYPE_FILELINK.equals(type)) + { + // create our File Link Node representation + node = new MapNode(nodeRef, this.nodeService, false); + node.addPropertyResolver("url", this.resolverLinkUrl); + node.addPropertyResolver("webdavUrl", this.resolverLinkWebdavUrl); + node.addPropertyResolver("cifsPath", this.resolverLinkCifsPath); + node.addPropertyResolver("fileType16", this.resolverFileType16); + node.addPropertyResolver("fileType32", this.resolverFileType32); + node.addPropertyResolver("size", this.resolverSize); + node.addPropertyResolver("path", this.resolverPath); + node.addPropertyResolver("displayPath", this.resolverDisplayPath); + + this.contentNodes.add(node); + } + else if (ContentModel.TYPE_FOLDERLINK.equals(type)) + { + // create our Folder Link Node representation + node = new MapNode(nodeRef, this.nodeService, false); + node.addPropertyResolver("icon", this.resolverSpaceIcon); + node.addPropertyResolver("smallIcon", this.resolverSmallIcon); + node.addPropertyResolver("path", this.resolverPath); + node.addPropertyResolver("displayPath", this.resolverDisplayPath); + + this.containerNodes.add(node); + } + + // inform any listeners that a Node wrapper has been created + if (node != null) + { + for (NodeEventListener listener : getNodeEventListeners()) + { + listener.created(node, type); + } + } + } + else + { + if (logger.isEnabledFor(Priority.WARN)) + logger.warn("Found invalid object in database: id = " + nodeRef + ", type = " + type); + } + } + else + { + if (logger.isEnabledFor(Priority.WARN)) + logger.warn("Missing object returned from search indexes: id = " + nodeRef + " search query: " + query); + } + } + } + + // commit the transaction + tx.commit(); + } + catch (InvalidNodeRefException refErr) + { + Utils.addErrorMessage(MessageFormat.format(Application.getMessage( + FacesContext.getCurrentInstance(), Repository.ERROR_NODEREF), new Object[] {refErr.getNodeRef()}) ); + this.containerNodes = Collections.emptyList(); + this.contentNodes = Collections.emptyList(); + try { if (tx != null) {tx.rollback();} } catch (Exception tex) {} + } + catch (Throwable err) + { + logger.info("Search failed for: " + query); + Utils.addErrorMessage(MessageFormat.format(Application.getMessage( + FacesContext.getCurrentInstance(), Repository.ERROR_SEARCH), new Object[] {err.getMessage()}), err ); + this.containerNodes = Collections.emptyList(); + this.contentNodes = Collections.emptyList(); + try { if (tx != null) {tx.rollback();} } catch (Exception tex) {} + } + finally + { + if (results != null) + { + results.close(); + } + } + + if (logger.isDebugEnabled()) + { + long endTime = System.currentTimeMillis(); + logger.debug("Time to query and build map nodes: " + (endTime - startTime) + "ms"); + } + } + + + // ------------------------------------------------------------------------------ + // Property Resolvers + + public NodePropertyResolver resolverDownload = new NodePropertyResolver() { + public Object get(Node node) { + return DownloadContentServlet.generateDownloadURL(node.getNodeRef(), node.getName()); + } + }; + + public NodePropertyResolver resolverUrl = new NodePropertyResolver() { + public Object get(Node node) { + return DownloadContentServlet.generateBrowserURL(node.getNodeRef(), node.getName()); + } + }; + + public NodePropertyResolver resolverWebdavUrl = new NodePropertyResolver() { + public Object get(Node node) { + return Utils.generateURL(FacesContext.getCurrentInstance(), node, URLMode.WEBDAV); + } + }; + + public NodePropertyResolver resolverCifsPath = new NodePropertyResolver() { + public Object get(Node node) { + return Utils.generateURL(FacesContext.getCurrentInstance(), node, URLMode.CIFS); + } + }; + + public NodePropertyResolver resolverLinkDownload = new NodePropertyResolver() { + public Object get(Node node) { + NodeRef destRef = (NodeRef)node.getProperties().get(ContentModel.PROP_LINK_DESTINATION); + if (nodeService.exists(destRef) == true) + { + String destName = Repository.getNameForNode(nodeService, destRef); + return DownloadContentServlet.generateDownloadURL(node.getNodeRef(), destName); + } + else + { + // TODO: link object is missing - navigate to a page with appropriate message + return "#"; + } + } + }; + + public NodePropertyResolver resolverLinkUrl = new NodePropertyResolver() { + public Object get(Node node) { + NodeRef destRef = (NodeRef)node.getProperties().get(ContentModel.PROP_LINK_DESTINATION); + if (nodeService.exists(destRef) == true) + { + String destName = Repository.getNameForNode(nodeService, destRef); + return DownloadContentServlet.generateBrowserURL(destRef, destName); + } + else + { + // TODO: link object is missing - navigate to a page with appropriate message + return "#"; + } + } + }; + + public NodePropertyResolver resolverLinkWebdavUrl = new NodePropertyResolver() { + public Object get(Node node) { + NodeRef destRef = (NodeRef)node.getProperties().get(ContentModel.PROP_LINK_DESTINATION); + if (nodeService.exists(destRef) == true) + { + return Utils.generateURL(FacesContext.getCurrentInstance(), new Node(destRef), URLMode.WEBDAV); + } + else + { + // TODO: link object is missing - navigate to a page with appropriate message + return "#"; + } + } + }; + + public NodePropertyResolver resolverLinkCifsPath = new NodePropertyResolver() { + public Object get(Node node) { + NodeRef destRef = (NodeRef)node.getProperties().get(ContentModel.PROP_LINK_DESTINATION); + if (nodeService.exists(destRef) == true) + { + return Utils.generateURL(FacesContext.getCurrentInstance(), new Node(destRef), URLMode.CIFS); + } + else + { + // TODO: link object is missing - navigate to a page with appropriate message + return "#"; + } + } + }; + + public NodePropertyResolver resolverFileType16 = new NodePropertyResolver() { + public Object get(Node node) { + return Utils.getFileTypeImage(node.getName(), true); + } + }; + + public NodePropertyResolver resolverFileType32 = new NodePropertyResolver() { + public Object get(Node node) { + return Utils.getFileTypeImage(node.getName(), false); + } + }; + + public NodePropertyResolver resolverPath = new NodePropertyResolver() { + public Object get(Node node) { + return nodeService.getPath(node.getNodeRef()); + } + }; + + public NodePropertyResolver resolverDisplayPath = new NodePropertyResolver() { + public Object get(Node node) { + // TODO: replace this with a method that shows the full display name - not QNames? + return Repository.getDisplayPath( (Path)node.getProperties().get("path") ); + } + }; + + public NodePropertyResolver resolverSpaceIcon = new NodePropertyResolver() { + public Object get(Node node) { + QNameNodeMap props = (QNameNodeMap)node.getProperties(); + String icon = (String)props.getRaw("app:icon"); + return (icon != null ? icon : CreateSpaceWizard.DEFAULT_SPACE_ICON_NAME); + } + }; + + public NodePropertyResolver resolverSmallIcon = new NodePropertyResolver() { + public Object get(Node node) { + QNameNodeMap props = (QNameNodeMap)node.getProperties(); + String icon = (String)props.getRaw("app:icon"); + return (icon != null ? icon + "-16" : SPACE_SMALL_DEFAULT); + } + }; + + public NodePropertyResolver resolverMimetype = new NodePropertyResolver() { + public Object get(Node node) { + ContentData content = (ContentData)node.getProperties().get(ContentModel.PROP_CONTENT); + return (content != null ? content.getMimetype() : null); + } + }; + + public NodePropertyResolver resolverSize = new NodePropertyResolver() { + public Object get(Node node) { + ContentData content = (ContentData)node.getProperties().get(ContentModel.PROP_CONTENT); + return (content != null ? new Long(content.getSize()) : 0L); + } + }; + + + // ------------------------------------------------------------------------------ + // Navigation action event handlers + + /** + * Action called from the Simple Search component. + * Sets up the SearchContext object with the values from the simple search menu. + */ + public void search(ActionEvent event) + { + // setup the search text string on the top-level navigation handler + UISimpleSearch search = (UISimpleSearch)event.getComponent(); + this.navigator.setSearchContext(search.getSearchContext()); + + navigateBrowseScreen(); + } + + /** + * Action called to Close the search dialog by returning to the last view node Id + */ + public void closeSearch(ActionEvent event) + { + // set the current node Id ready for page refresh + this.navigator.setCurrentNodeId( this.navigator.getCurrentNodeId() ); + } + + /** + * Update page size based on user selection + */ + public void updateSpacesPageSize(ActionEvent event) + { + try + { + int size = Integer.parseInt(this.pageSizeSpacesStr); + if (size >= 0) + { + this.pageSizeSpaces = size; + } + else + { + // reset to known value if this occurs + this.pageSizeSpacesStr = Integer.toString(this.pageSizeSpaces); + } + } + catch (NumberFormatException err) + { + // reset to known value if this occurs + this.pageSizeSpacesStr = Integer.toString(this.pageSizeSpaces); + } + } + + /** + * Update page size based on user selection + */ + public void updateContentPageSize(ActionEvent event) + { + try + { + int size = Integer.parseInt(this.pageSizeContentStr); + if (size >= 0) + { + this.pageSizeContent = size; + } + else + { + // reset to known value if this occurs + this.pageSizeContentStr = Integer.toString(this.pageSizeContent); + } + } + catch (NumberFormatException err) + { + // reset to known value if this occurs + this.pageSizeContentStr = Integer.toString(this.pageSizeContent); + } + } + + /** + * Action called when a folder space is clicked. + * Navigate into the space. + */ + public void clickSpace(ActionEvent event) + { + UIActionLink link = (UIActionLink)event.getComponent(); + Map params = link.getParameterMap(); + String id = params.get("id"); + if (id != null && id.length() != 0) + { + try + { + NodeRef ref = new NodeRef(Repository.getStoreRef(), id); + + // handle special folder link node case + if (ContentModel.TYPE_FOLDERLINK.equals(this.nodeService.getType(ref))) + { + ref = (NodeRef)this.nodeService.getProperty(ref, ContentModel.PROP_LINK_DESTINATION); + } + + clickSpace(ref); + } + catch (InvalidNodeRefException refErr) + { + Utils.addErrorMessage(MessageFormat.format(Application.getMessage( + FacesContext.getCurrentInstance(), Repository.ERROR_NODEREF), new Object[] {id}) ); + } + } + } + + /** + * Action called when a folder space is clicked. + * + * @param nodeRef The node being clicked + */ + public void clickSpace(NodeRef nodeRef) + { + // refresh UI based on node selection + updateUILocation(nodeRef); + } + + /** + * Handler called when a path element is clicked - navigate to the appropriate Space + */ + public void clickSpacePath(ActionEvent event) + { + UINodePath.PathElementEvent pathEvent = (UINodePath.PathElementEvent)event; + NodeRef ref = pathEvent.NodeReference; + try + { + // refresh UI based on node selection + this.updateUILocation(ref); + } + catch (InvalidNodeRefException refErr) + { + Utils.addErrorMessage(MessageFormat.format(Application.getMessage( + FacesContext.getCurrentInstance(), Repository.ERROR_NODEREF), new Object[] {ref.getId()}) ); + } + } + + /** + * Action called when a folders direct descendant (in the 'list' browse mode) is clicked. + * Navigate into the the descendant space. + */ + public void clickDescendantSpace(ActionEvent event) + { + UINodeDescendants.NodeSelectedEvent nodeEvent = (UINodeDescendants.NodeSelectedEvent)event; + NodeRef nodeRef = nodeEvent.NodeReference; + if (nodeRef == null) + { + throw new IllegalStateException("NodeRef returned from UINodeDescendants.NodeSelectedEvent cannot be null!"); + } + + if (logger.isDebugEnabled()) + logger.debug("Selected noderef Id: " + nodeRef.getId()); + + try + { + // user can either select a descendant of a node display on the page which means we + // must add the it's parent and itself to the breadcrumb + ChildAssociationRef parentAssocRef = nodeService.getPrimaryParent(nodeRef); + + if (logger.isDebugEnabled()) + { + logger.debug("Selected item getPrimaryParent().getChildRef() noderef Id: " + parentAssocRef.getChildRef().getId()); + logger.debug("Selected item getPrimaryParent().getParentRef() noderef Id: " + parentAssocRef.getParentRef().getId()); + logger.debug("Current value getNavigator().getCurrentNodeId() noderef Id: " + this.navigator.getCurrentNodeId()); + } + + if (nodeEvent.IsParent == false) + { + // a descendant of the displayed node was selected + // first refresh based on the parent and add to the breadcrumb + updateUILocation(parentAssocRef.getParentRef()); + + // now add our selected node + updateUILocation(nodeRef); + } + else + { + // else the parent ellipses i.e. the displayed node was selected + updateUILocation(nodeRef); + } + } + catch (InvalidNodeRefException refErr) + { + Utils.addErrorMessage(MessageFormat.format(Application.getMessage( + FacesContext.getCurrentInstance(), Repository.ERROR_NODEREF), new Object[] {nodeRef.getId()}) ); + } + } + + /** + * Action event called by all Browse actions that need to setup a Space context + * before an action page/wizard is called. The context will be a Node in setActionSpace() which + * can be retrieved on the action page from BrowseBean.getActionSpace(). + * + * @param event ActionEvent + */ + public void setupSpaceAction(ActionEvent event) + { + UIActionLink link = (UIActionLink)event.getComponent(); + Map params = link.getParameterMap(); + String id = params.get("id"); + setupSpaceAction(id, true); + } + + /** + * Public helper to setup action pages with Space context + * + * @param id of the Space node to setup context for + */ + public void setupSpaceAction(String id, boolean invalidate) + { + if (id != null && id.length() != 0) + { + if (logger.isDebugEnabled()) + logger.debug("Setup for action, setting current space to: " + id); + + try + { + // create the node ref, then our node representation + NodeRef ref = new NodeRef(Repository.getStoreRef(), id); + Node node = new Node(ref); + + // resolve icon in-case one has not been set + node.addPropertyResolver("icon", this.resolverSpaceIcon); + + // prepare a node for the action context + setActionSpace(node); + + // setup the dispatch context in case it is required + this.navigator.setupDispatchContext(node); + } + catch (InvalidNodeRefException refErr) + { + Utils.addErrorMessage(MessageFormat.format(Application.getMessage( + FacesContext.getCurrentInstance(), Repository.ERROR_NODEREF), new Object[] {id}) ); + } + } + else + { + setActionSpace(null); + } + + // clear the UI state in preparation for finishing the next action + if (invalidate == true) + { + // use the context service to notify all registered beans + UIContextService.getInstance(FacesContext.getCurrentInstance()).notifyBeans(); + } + } + + /** + * Acrtion event called by Delete Space actions. We setup the action space as normal, then prepare + * any special case message string to be shown to the user if they are trying to delete specific spaces. + */ + public void setupDeleteAction(ActionEvent event) + { + String message = null; + + setupSpaceAction(event); + + Node node = getActionSpace(); + if (node != null) + { + NodeRef companyRootRef = new NodeRef(Repository.getStoreRef(), Application.getCompanyRootId()); + if (node.getNodeRef().equals(companyRootRef)) + { + message = Application.getMessage(FacesContext.getCurrentInstance(), MSG_DELETE_COMPANYROOT); + } + } + + setDeleteMessage(message); + } + + /** + * Action event called by all actions that need to setup a Content Document context on the + * BrowseBean before an action page/wizard is called. The context will be a Node in + * setDocument() which can be retrieved on the action page from BrowseBean.getDocument(). + */ + public void setupContentAction(ActionEvent event) + { + UIActionLink link = (UIActionLink)event.getComponent(); + Map params = link.getParameterMap(); + setupContentAction(params.get("id"), true); + } + + /** + * Public helper to setup action pages with content context + * + * @param id of the content node to setup context for + */ + public void setupContentAction(String id, boolean invalidate) + { + if (id != null && id.length() != 0) + { + if (logger.isDebugEnabled()) + logger.debug("Setup for action, setting current document to: " + id); + + try + { + // create the node ref, then our node representation + NodeRef ref = new NodeRef(Repository.getStoreRef(), id); + Node node = new Node(ref); + + // store the URL to for downloading the content + if (ContentModel.TYPE_FILELINK.equals(node.getType())) + { + node.addPropertyResolver("url", this.resolverLinkDownload); + } + else + { + node.addPropertyResolver("url", this.resolverDownload); + } + node.addPropertyResolver("fileType32", this.resolverFileType32); + node.addPropertyResolver("mimetype", this.resolverMimetype); + node.addPropertyResolver("size", this.resolverSize); + + for (NodeEventListener listener : getNodeEventListeners()) + { + listener.created(node, node.getType()); + } + + // get hold of the DocumentDetailsBean and reset it + DocumentDetailsBean docDetails = (DocumentDetailsBean)FacesContext.getCurrentInstance(). + getExternalContext().getSessionMap().get("DocumentDetailsBean"); + if (docDetails != null) + { + docDetails.reset(); + } + + // remember the document + setDocument(node); + + // setup the dispatch context in case it is required + this.navigator.setupDispatchContext(node); + } + catch (InvalidNodeRefException refErr) + { + Utils.addErrorMessage(MessageFormat.format(Application.getMessage( + FacesContext.getCurrentInstance(), Repository.ERROR_NODEREF), new Object[] {id}) ); + } + } + else + { + setDocument(null); + } + + // clear the UI state in preparation for finishing the next action + if (invalidate == true) + { + // use the context service to notify all registered beans + UIContextService.getInstance(FacesContext.getCurrentInstance()).notifyBeans(); + } + } + + /** + * Removes the given node from the breadcrumb i.e. following a delete + * + * @param node The space to remove from the breadcrumb + */ + public void removeSpaceFromBreadcrumb(Node node) + { + List location = navigator.getLocation(); + IBreadcrumbHandler handler = location.get(location.size() - 1); + if (handler instanceof BrowseBreadcrumbHandler) + { + // see if the current breadcrumb location is our node + if ( ((BrowseBreadcrumbHandler)handler).getNodeRef().equals(node.getNodeRef()) == true ) + { + location.remove(location.size() - 1); + + // now work out which node to set the list to refresh against + if (location.size() != 0) + { + handler = location.get(location.size() - 1); + if (handler instanceof BrowseBreadcrumbHandler) + { + // change the current node Id + navigator.setCurrentNodeId(((BrowseBreadcrumbHandler)handler).getNodeRef().getId()); + } + else + { + // TODO: shouldn't do this - but for now the user home dir is the root! + navigator.setCurrentNodeId(Application.getCurrentUser(FacesContext.getCurrentInstance()).getHomeSpaceId()); + } + } + } + } + } + + /** + * Support for refresh of lists via special case for an External Access URL. + * these URLs restart the JSF lifecycle but an old UIRichList is restored from + * the component tree - which needs clearing "late" in the lifecycle process. + */ + public void externalAccessRefresh() + { + this.externalForceRefresh = true; + } + + /** + * Save the state of the panel that was expanded/collapsed + */ + public void expandPanel(ActionEvent event) + { + if (event instanceof ExpandedEvent) + { + String id = event.getComponent().getId(); + this.panels.put(id, ((ExpandedEvent)event).State); + } + } + + + // ------------------------------------------------------------------------------ + // Private helpers + + /** + * Initialise default values from client configuration + */ + private void initFromClientConfig() + { + ConfigService config = Application.getConfigService(FacesContext.getCurrentInstance()); + + this.viewsConfig = (ViewsConfigElement)config.getConfig("Views"). + getConfigElement(ViewsConfigElement.CONFIG_ELEMENT_ID); + + this.browseViewMode = this.viewsConfig.getDefaultView(PAGE_NAME_BROWSE); + int pageSize = this.viewsConfig.getDefaultPageSize(PAGE_NAME_BROWSE, this.browseViewMode); + setPageSizeContent(pageSize); + setPageSizeSpaces(pageSize); + } + + /** + * @return the Set of NodeEventListeners registered against this bean + */ + private Set getNodeEventListeners() + { + if (this.nodeEventListeners == null) + { + this.nodeEventListeners = new HashSet(); + + FacesContext fc = FacesContext.getCurrentInstance(); + + Config listenerConfig = Application.getConfigService(fc).getConfig("Node Event Listeners"); + if (listenerConfig != null) + { + ConfigElement listenerElement = listenerConfig.getConfigElement("node-event-listeners"); + if (listenerElement != null) + { + for (ConfigElement child : listenerElement.getChildren()) + { + if (child.getName().equals("listener")) + { + // retrieved the JSF Managed Bean identified in the config + String listenerName = child.getValue().trim(); + Object bean = FacesHelper.getManagedBean(fc, listenerName); + if (bean instanceof NodeEventListener) + { + addNodeEventListener((NodeEventListener)bean); + } + } + } + } + } + } + return this.nodeEventListeners; + } + + /** + * Refresh the UI after a Space selection change. Adds the selected space to the breadcrumb + * location path and also updates the list components in the UI. + * + * @param ref NodeRef of the selected space + */ + public void updateUILocation(NodeRef ref) + { + // get the current breadcrumb location and append a new handler to it + // our handler know the ID of the selected node and the display label for it + List location = this.navigator.getLocation(); + if (location.size() != 0) + { + // attempt to find the ID - if it's already in the breadcrumb then we + // navigate directly to that node - rather than add duplication to the breadcrumb path + boolean foundNode = false; + for (int i=0; i newLocation = new ArrayList(i+1); + //newLocation.addAll(location.subList(0, i + 1)); + //this.navigator.setLocation(newLocation); + // TODO: but instead for now we do this: + int count = location.size(); + for (int n=i+1; n nodeEventListeners = null; + + /** Collapsable Panel state */ + private Map panels = new HashMap(4, 1.0f); + + /** Component references */ + protected UIRichList spacesRichList; + protected UIRichList contentRichList; + private UIStatusMessage statusMessage; + + /** Transient lists of container and content nodes for display */ + protected List containerNodes = null; + protected List contentNodes = null; + + /** The current space and it's properties - if any */ + protected Node actionSpace; + + /** The current document */ + protected Node document; + + /** Special message to display when user deleting certain folders e.g. Company Home */ + private String deleteMessage; + + /** The current browse view mode - set to a well known IRichListRenderer identifier */ + private String browseViewMode; + + /** The current browse view page sizes */ + private int pageSizeSpaces; + private int pageSizeContent; + private String pageSizeSpacesStr; + private String pageSizeContentStr; + + /** True if current space has a dashboard (template) view available */ + private boolean dashboardView; + + private boolean externalForceRefresh = false; +} diff --git a/source/java/org/alfresco/web/bean/CheckinCheckoutBean.java b/source/java/org/alfresco/web/bean/CheckinCheckoutBean.java index 365bc43134..4f0c938ad5 100644 --- a/source/java/org/alfresco/web/bean/CheckinCheckoutBean.java +++ b/source/java/org/alfresco/web/bean/CheckinCheckoutBean.java @@ -1,988 +1,986 @@ -/* - * Copyright (C) 2005 Alfresco, Inc. - * - * Licensed under the Mozilla Public License version 1.1 - * with a permitted attribution clause. You may obtain a - * copy of the License at - * - * http://www.alfresco.org/legal/license.txt - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, - * either express or implied. See the License for the specific - * language governing permissions and limitations under the - * License. - */ -package org.alfresco.web.bean; - -import java.io.File; -import java.io.Serializable; -import java.text.MessageFormat; -import java.util.HashMap; -import java.util.Map; - -import javax.faces.context.FacesContext; -import javax.faces.event.ActionEvent; -import javax.transaction.UserTransaction; - -import org.alfresco.model.ContentModel; -import org.alfresco.repo.content.MimetypeMap; -import org.alfresco.repo.version.VersionModel; -import org.alfresco.service.cmr.coci.CheckOutCheckInService; -import org.alfresco.service.cmr.repository.ChildAssociationRef; -import org.alfresco.service.cmr.repository.ContentData; -import org.alfresco.service.cmr.repository.ContentReader; -import org.alfresco.service.cmr.repository.ContentService; -import org.alfresco.service.cmr.repository.ContentWriter; -import org.alfresco.service.cmr.repository.InvalidNodeRefException; -import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.cmr.repository.NodeService; -import org.alfresco.service.cmr.version.Version; -import org.alfresco.service.cmr.version.VersionType; -import org.alfresco.web.app.AlfrescoNavigationHandler; -import org.alfresco.web.app.Application; -import org.alfresco.web.app.context.UIContextService; -import org.alfresco.web.app.servlet.DownloadContentServlet; -import org.alfresco.web.bean.repository.Node; -import org.alfresco.web.bean.repository.Repository; -import org.alfresco.web.templating.OutputUtil; -import org.alfresco.web.templating.TemplatingService; -import org.alfresco.web.ui.common.Utils; -import org.alfresco.web.ui.common.component.UIActionLink; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * @author Kevin Roast - */ -public class CheckinCheckoutBean -{ - // ------------------------------------------------------------------------------ - // Bean property getters and setters - - /** - * @param navigator The NavigationBean to set. - */ - public void setNavigator(NavigationBean navigator) - { - this.navigator = navigator; - } - - /** - * @return Returns the BrowseBean. - */ - public BrowseBean getBrowseBean() - { - return this.browseBean; - } - - /** - * @param browseBean The BrowseBean to set. - */ - public void setBrowseBean(BrowseBean browseBean) - { - this.browseBean = browseBean; - } - - /** - * @return Returns the NodeService. - */ - public NodeService getNodeService() - { - return this.nodeService; - } - - /** - * @param nodeService The NodeService to set. - */ - public void setNodeService(NodeService nodeService) - { - this.nodeService = nodeService; - } - - /** - * @return Returns the VersionOperationsService. - */ - public CheckOutCheckInService getVersionOperationsService() - { - return this.versionOperationsService; - } - - /** - * @param versionOperationsService The VersionOperationsService to set. - */ - public void setVersionOperationsService(CheckOutCheckInService versionOperationsService) - { - this.versionOperationsService = versionOperationsService; - } - - /** - * @return Returns the ContentService. - */ - public ContentService getContentService() - { - return this.contentService; - } - - /** - * @param contentService The ContentService to set. - */ - public void setContentService(ContentService contentService) - { - this.contentService = contentService; - } - - /** - * @return The document node being used for the current operation - */ - public Node getDocument() - { - return this.document; - } - - /** - * @param document The document node to be used for the current operation - */ - public void setDocument(Node document) - { - this.document = document; - } - - /** - * @return Returns the working copy Document. - */ - public Node getWorkingDocument() - { - return this.workingDocument; - } - - /** - * @param workingDocument The working copy Document to set. - */ - public void setWorkingDocument(Node workingDocument) - { - this.workingDocument = workingDocument; - } - - /** - * Determines whether the document being checked in has - * the versionable aspect applied - * - * @return true if the versionable aspect is applied - */ - public boolean isVersionable() - { - return getDocument().hasAspect(ContentModel.ASPECT_VERSIONABLE); - } - - /** - * @param keepCheckedOut The keepCheckedOut to set. - */ - public void setKeepCheckedOut(boolean keepCheckedOut) - { - this.keepCheckedOut = keepCheckedOut; - } - - /** - * @return Returns the keepCheckedOut. - */ - public boolean getKeepCheckedOut() - { - return this.keepCheckedOut; - } - - /** - * @param minorChange The minorChange to set. - */ - public void setMinorChange(boolean minorChange) - { - this.minorChange = minorChange; - } - - /** - * @return Returns the minorChange flag. - */ - public boolean getMinorChange() - { - return this.minorChange; - } - - /** - * @return Returns the version history notes. - */ - public String getVersionNotes() - { - return this.versionNotes; - } - - /** - * @param versionNotes The version history notes to set. - */ - public void setVersionNotes(String versionNotes) - { - this.versionNotes = versionNotes; - } - - /** - * @return Returns the selected Space Id. - */ - public NodeRef getSelectedSpaceId() - { - return this.selectedSpaceId; - } - - /** - * @param selectedSpaceId The selected Space Id to set. - */ - public void setSelectedSpaceId(NodeRef selectedSpaceId) - { - this.selectedSpaceId = selectedSpaceId; - } - - /** - * @return Returns the copy location. Either the current or other space. - */ - public String getCopyLocation() - { - if (this.fileName != null) - { - return CheckinCheckoutBean.COPYLOCATION_OTHER; - } - else - { - return this.copyLocation; - } - } - - /** - * @param copyLocation The copy location. Either the current or other space. - */ - public void setCopyLocation(String copyLocation) - { - this.copyLocation = copyLocation; - } - - /** - * @return Returns the message to display when a file has been uploaded - */ - public String getFileUploadSuccessMsg() - { - String msg = Application.getMessage(FacesContext.getCurrentInstance(), "file_upload_success"); - return MessageFormat.format(msg, new Object[] {getFileName()}); - } - - /** - * @return Returns the name of the file - */ - public String getFileName() - { - // try and retrieve the file and filename from the file upload bean - // representing the file we previously uploaded. - FacesContext ctx = FacesContext.getCurrentInstance(); - FileUploadBean fileBean = (FileUploadBean)ctx.getExternalContext().getSessionMap(). - get(FileUploadBean.FILE_UPLOAD_BEAN_NAME); - if (fileBean != null) - { - this.file = fileBean.getFile(); - this.fileName = fileBean.getFileName(); - } - - return this.fileName; - } - - /** - * @param fileName The name of the file - */ - public void setFileName(String fileName) - { - this.fileName = fileName; - - // we also need to keep the file upload bean in sync - FacesContext ctx = FacesContext.getCurrentInstance(); - FileUploadBean fileBean = (FileUploadBean)ctx.getExternalContext().getSessionMap(). - get(FileUploadBean.FILE_UPLOAD_BEAN_NAME); - if (fileBean != null) - { - fileBean.setFileName(this.fileName); - } - } - - /** - * @return Returns the document content used for HTML in-line editing. - */ - public String getDocumentContent() - { - return this.documentContent; - } - - /** - * @param documentContent The document content for HTML in-line editing. - */ - public void setDocumentContent(String documentContent) - { - this.documentContent = documentContent; - } - - /** - * @return Returns output from the in-line editor page. - */ - public String getEditorOutput() - { - return this.editorOutput; - } - - /** - * @param editorOutput The output from the in-line editor page - */ - public void setEditorOutput(String editorOutput) - { - this.editorOutput = editorOutput; - } - - - // ------------------------------------------------------------------------------ - // Navigation action event handlers - - /** - * Action event called by all actions that need to setup a Content Document context on the - * CheckinCheckoutBean before an action page/wizard is called. The context will be a Node in - * setDocument() which can be retrieved on action pages via getDocument(). - * - * @param event ActionEvent - */ - public void setupContentAction(ActionEvent event) - { - UIActionLink link = (UIActionLink)event.getComponent(); - Map params = link.getParameterMap(); - String id = params.get("id"); - if (id != null && id.length() != 0) - { - setupContentDocument(id); - } - else - { - setDocument(null); - } - - clearUpload(); - } - - /** - * Setup a content document node context - * - * @param id GUID of the node to setup as the content document context - * - * @return The Node - */ - private Node setupContentDocument(String id) - { - if (LOGGER.isDebugEnabled()) - LOGGER.debug("Setup for action, setting current document to: " + id); - - Node node = null; - - try - { - // create the node ref, then our node representation - NodeRef ref = new NodeRef(Repository.getStoreRef(), id); - node = new Node(ref); - - // create content URL to the content download servlet with ID and expected filename - // the myfile part will be ignored by the servlet but gives the browser a hint - String url = DownloadContentServlet.generateDownloadURL(ref, node.getName()); - node.getProperties().put("url", url); - node.getProperties().put("workingCopy", node.hasAspect(ContentModel.ASPECT_WORKING_COPY)); - node.getProperties().put("fileType32", Utils.getFileTypeImage(node.getName(), false)); - - // remember the document - setDocument(node); - - // refresh the UI, calling this method now is fine as it basically makes sure certain - // beans clear the state - so when we finish here other beans will have been reset - UIContextService.getInstance(FacesContext.getCurrentInstance()).notifyBeans(); - } - catch (InvalidNodeRefException refErr) - { - Utils.addErrorMessage(MessageFormat.format(Application.getMessage( - FacesContext.getCurrentInstance(), Repository.ERROR_NODEREF), new Object[] {id}) ); - } - - return node; - } - - /** - * Action called upon completion of the Check Out file page - */ - public String checkoutFile() - { - String outcome = null; - - UserTransaction tx = null; - - Node node = getDocument(); - if (node != null) - { - try - { - tx = Repository.getUserTransaction(FacesContext.getCurrentInstance()); - tx.begin(); - - if (LOGGER.isDebugEnabled()) - LOGGER.debug("Trying to checkout content node Id: " + node.getId()); - - // checkout the node content to create a working copy - if (LOGGER.isDebugEnabled()) - { - LOGGER.debug("Checkout copy location: " + getCopyLocation()); - LOGGER.debug("Selected Space Id: " + this.selectedSpaceId); - } - NodeRef workingCopyRef; - if (getCopyLocation().equals(COPYLOCATION_OTHER) && this.selectedSpaceId != null) - { - // checkout to a arbituary parent Space - NodeRef destRef = this.selectedSpaceId; - - ChildAssociationRef childAssocRef = this.nodeService.getPrimaryParent(destRef); - workingCopyRef = this.versionOperationsService.checkout(node.getNodeRef(), - destRef, ContentModel.ASSOC_CONTAINS, childAssocRef.getQName()); - } - else - { - workingCopyRef = this.versionOperationsService.checkout(node.getNodeRef()); - } - - // set the working copy Node instance - Node workingCopy = new Node(workingCopyRef); - setWorkingDocument(workingCopy); - - // create content URL to the content download servlet with ID and expected filename - // the myfile part will be ignored by the servlet but gives the browser a hint - String url = DownloadContentServlet.generateDownloadURL(workingCopyRef, workingCopy.getName()); - - workingCopy.getProperties().put("url", url); - workingCopy.getProperties().put("fileType32", Utils.getFileTypeImage(workingCopy.getName(), false)); - - // commit the transaction - tx.commit(); - - // show the page that display the checkout link - outcome = "checkoutFileLink"; - } - catch (Throwable err) - { - // rollback the transaction - try { if (tx != null) {tx.rollback();} } catch (Exception tex) {} - Utils.addErrorMessage(Application.getMessage( - FacesContext.getCurrentInstance(), MSG_ERROR_CHECKOUT) + err.getMessage(), err); - } - } - else - { - LOGGER.warn("WARNING: checkoutFile called without a current Document!"); - } - - return outcome; - } - - /** - * Action called upon completion of the Check Out file Link download page - */ - public String checkoutFileOK() - { - String outcome = null; - - Node node = getWorkingDocument(); - if (node != null) - { - // reset the underlying node - if (this.browseBean.getDocument() != null) - { - this.browseBean.getDocument().reset(); - } - - // clean up and clear action context - clearUpload(); - setDocument(null); - setWorkingDocument(null); - - outcome = AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME; - } - else - { - LOGGER.warn("WARNING: checkoutFileOK called without a current WorkingDocument!"); - } - - return outcome; - } - - /** - * Action called upon completion of the Edit File download page - */ - public String editFileOK() - { - String outcome = null; - - Node node = getDocument(); - if (node != null) - { - // clean up and clear action context - clearUpload(); - setDocument(null); - setWorkingDocument(null); - - outcome = AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME; - } - else - { - LOGGER.warn("WARNING: editFileOK called without a current Document!"); - } - - return outcome; - } - - /** - * Action handler called to calculate which editing screen to display based on the mimetype - * of a document. If appropriate, the in-line editing screen will be shown. - */ - public void editFile(ActionEvent event) - { - UIActionLink link = (UIActionLink)event.getComponent(); - Map params = link.getParameterMap(); - String id = params.get("id"); - if (id != null && id.length() != 0) - { - boolean editingInline = false; - Node node = setupContentDocument(id); - - // detect the inline editing aspect to see which edit mode to use - if (node.hasAspect(ContentModel.ASPECT_INLINEEDITABLE) && - node.getProperties().get(ContentModel.PROP_EDITINLINE) != null && - ((Boolean)node.getProperties().get(ContentModel.PROP_EDITINLINE)).booleanValue() == true) - { - // retrieve the content reader for this node - ContentReader reader = getContentService().getReader(node.getNodeRef(), ContentModel.PROP_CONTENT); - if (reader != null) - { - editingInline = true; - String mimetype = reader.getMimetype(); - - // calculate which editor screen to display - if (MimetypeMap.MIMETYPE_TEXT_PLAIN.equals(mimetype) || - MimetypeMap.MIMETYPE_XML.equals(mimetype) || - MimetypeMap.MIMETYPE_TEXT_CSS.equals(mimetype) || - MimetypeMap.MIMETYPE_JAVASCRIPT.equals(mimetype)) - { - // make content available to the editing screen - String contentString = reader.getContentString(); - setDocumentContent(contentString); - setEditorOutput(contentString); - - // navigate to appropriate screen - FacesContext fc = FacesContext.getCurrentInstance(); - this.navigator.setupDispatchContext(node); - String s = (MimetypeMap.MIMETYPE_XML.equals(mimetype) - ? "dialog:editXmlInline" - : "dialog:editTextInline"); - fc.getApplication().getNavigationHandler().handleNavigation(fc, null, s); - - } - else - { - // make content available to the editing screen - setDocumentContent(reader.getContentString()); - setEditorOutput(null); - - // navigate to appropriate screen - FacesContext fc = FacesContext.getCurrentInstance(); - this.navigator.setupDispatchContext(node); - fc.getApplication().getNavigationHandler().handleNavigation(fc, null, "dialog:editHtmlInline"); - } - } - } - - if (editingInline == false) - { - // normal downloadable document - FacesContext fc = FacesContext.getCurrentInstance(); - this.navigator.setupDispatchContext(node); - fc.getApplication().getNavigationHandler().handleNavigation(fc, null, "dialog:editFile"); - } - } - } - - /** - * Action handler called to set the content of a node from an inline editing page. - */ - public String editInlineOK() - { - String outcome = null; - - UserTransaction tx = null; - - Node node = getDocument(); - if (node != null) - { - try - { - tx = Repository.getUserTransaction(FacesContext.getCurrentInstance()); - tx.begin(); - - if (LOGGER.isDebugEnabled()) - LOGGER.debug("Trying to update content node Id: " + node.getId()); - - // get an updating writer that we can use to modify the content on the current node - ContentWriter writer = this.contentService.getWriter(node.getNodeRef(), ContentModel.PROP_CONTENT, true); - writer.putContent(this.editorOutput); - - // commit the transaction - tx.commit(); - - if (nodeService.getProperty(node.getNodeRef(), - TemplatingService.TT_QNAME) != null) - { - OutputUtil.regenerate(node.getNodeRef(), - this.contentService, - this.nodeService); - } - - // clean up and clear action context - clearUpload(); - setDocument(null); - setDocumentContent(null); - setEditorOutput(null); - - outcome = AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME; - } - catch (Throwable err) - { - // rollback the transaction - try { if (tx != null) {tx.rollback();} } catch (Exception tex) {} - Utils.addErrorMessage(Application.getMessage( - FacesContext.getCurrentInstance(), MSG_ERROR_UPDATE) + err.getMessage()); - } - } - else - { - LOGGER.warn("WARNING: editInlineOK called without a current Document!"); - } - - return outcome; - } - - /** - * Action to undo the checkout of a document just checked out from the checkout screen. - */ - public String undoCheckout() - { - String outcome = null; - - Node node = getWorkingDocument(); - if (node != null) - { - try - { - // try to cancel checkout of the working copy - this.versionOperationsService.cancelCheckout(node.getNodeRef()); - - clearUpload(); - - outcome = AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME; - } - catch (Throwable err) - { - Utils.addErrorMessage(Application.getMessage( - FacesContext.getCurrentInstance(), MSG_ERROR_CANCELCHECKOUT) + err.getMessage(), err); - } - } - else - { - LOGGER.warn("WARNING: undoCheckout called without a current WorkingDocument!"); - } - - return outcome; - } - - /** - * Action to undo the checkout of a locked document. This document may either by the original copy - * or the working copy node. Therefore calculate which it is, if the working copy is found then - * we simply cancel checkout on that document. If the original copy is found then we need to find - * the appropriate working copy and perform the action on that node. - */ - public String undoCheckoutFile() - { - String outcome = null; - - Node node = getDocument(); - if (node != null) - { - try - { - if (node.hasAspect(ContentModel.ASPECT_WORKING_COPY)) - { - this.versionOperationsService.cancelCheckout(node.getNodeRef()); - } - else if (node.hasAspect(ContentModel.ASPECT_LOCKABLE)) - { - // TODO: find the working copy for this document and cancel the checkout on it - // is this possible? as currently only the workingcopy aspect has the copyReference - // attribute - this means we cannot find out where the copy is to cancel it! - // can we construct an XPath node lookup? - throw new RuntimeException("NOT IMPLEMENTED"); - } - else - { - throw new IllegalStateException("Node supplied for undo checkout has neither Working Copy or Locked aspect!"); - } - - clearUpload(); - - outcome = AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME + AlfrescoNavigationHandler.OUTCOME_SEPARATOR + "browse"; - } - catch (Throwable err) - { - Utils.addErrorMessage(MSG_ERROR_CANCELCHECKOUT + err.getMessage(), err); - } - } - else - { - LOGGER.warn("WARNING: undoCheckout called without a current WorkingDocument!"); - } - - return outcome; - } - - /** - * Action called upon completion of the Check In file page - */ - public String checkinFileOK() - { - String outcome = null; - - UserTransaction tx = null; - - // NOTE: for checkin the document node _is_ the working document! - Node node = getDocument(); - if (node != null && (getCopyLocation().equals(COPYLOCATION_CURRENT) || this.getFileName() != null)) - { - try - { - FacesContext context = FacesContext.getCurrentInstance(); - tx = Repository.getUserTransaction(context); - tx.begin(); - - if (LOGGER.isDebugEnabled()) - LOGGER.debug("Trying to checkin content node Id: " + node.getId()); - - // we can either checkin the content from the current working copy node - // which would have been previously updated by the user - String contentUrl; - if (getCopyLocation().equals(COPYLOCATION_CURRENT)) - { - ContentData contentData = (ContentData) node.getProperties().get(ContentModel.PROP_CONTENT); - contentUrl = (contentData == null ? null : contentData.getContentUrl()); - } - // or specify a specific file as the content instead - else - { - // add the content to an anonymous but permanent writer location - // we can then retrieve the URL to the content to to be set on the node during checkin - ContentWriter writer = this.contentService.getWriter(node.getNodeRef(), ContentModel.PROP_CONTENT, true); - // also update the mime type in case a different type of file is uploaded - String mimeType = Repository.getMimeTypeForFileName(context, this.fileName); - writer.setMimetype(mimeType); - writer.putContent(this.file); - contentUrl = writer.getContentUrl(); - } - - if (contentUrl == null || contentUrl.length() == 0) - { - throw new IllegalStateException("Content URL is empty for specified working copy content node!"); - } - - // add version history text to props - Map props = new HashMap(1, 1.0f); - props.put(Version.PROP_DESCRIPTION, this.versionNotes); - // set the flag for minor or major change - if (this.minorChange) - { - props.put(VersionModel.PROP_VERSION_TYPE, VersionType.MINOR); - } - else - { - props.put(VersionModel.PROP_VERSION_TYPE, VersionType.MAJOR); - } - - // perform the checkin - this.versionOperationsService.checkin(node.getNodeRef(), - props, contentUrl, this.keepCheckedOut); - - // commit the transaction - tx.commit(); - - // clear action context - setDocument(null); - clearUpload(); - - outcome = AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME + - AlfrescoNavigationHandler.OUTCOME_SEPARATOR + "browse"; - } - catch (Throwable err) - { - // rollback the transaction - try { if (tx != null) {tx.rollback();} } catch (Exception tex) {} - Utils.addErrorMessage(Application.getMessage( - FacesContext.getCurrentInstance(), MSG_ERROR_CHECKIN) + err.getMessage(), err); - } - } - else - { - LOGGER.warn("WARNING: checkinFileOK called without a current Document!"); - } - - return outcome; - } - - /** - * Action called upon completion of the Update File page - */ - public String updateFileOK() - { - String outcome = null; - - UserTransaction tx = null; - - // NOTE: for update the document node _is_ the working document! - Node node = getDocument(); - if (node != null && this.getFileName() != null) - { - try - { - FacesContext context = FacesContext.getCurrentInstance(); - tx = Repository.getUserTransaction(context); - tx.begin(); - - if (LOGGER.isDebugEnabled()) - LOGGER.debug("Trying to update content node Id: " + node.getId()); - - // get an updating writer that we can use to modify the content on the current node - ContentWriter writer = this.contentService.getWriter(node.getNodeRef(), ContentModel.PROP_CONTENT, true); - - // also update the mime type in case a different type of file is uploaded - String mimeType = Repository.getMimeTypeForFileName(context, this.fileName); - writer.setMimetype(mimeType); - - writer.putContent(this.file); - - // commit the transaction - tx.commit(); - - // clear action context - setDocument(null); - clearUpload(); - - outcome = AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME; - } - catch (Throwable err) - { - // rollback the transaction - try { if (tx != null) {tx.rollback();} } catch (Exception tex) {} - Utils.addErrorMessage(Application.getMessage( - FacesContext.getCurrentInstance(), MSG_ERROR_UPDATE) + err.getMessage(), err); - } - } - else - { - LOGGER.warn("WARNING: updateFileOK called without a current Document!"); - } - - return outcome; - } - - /** - * Deals with the cancel button being pressed on the check in file page - */ - public String cancel() - { - // reset the state - clearUpload(); - - return AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME; - } - - /** - * Clear form state and upload file bean - */ - private void clearUpload() - { - // delete the temporary file we uploaded earlier - if (this.file != null) - { - this.file.delete(); - } - - this.file = null; - this.fileName = null; - this.keepCheckedOut = false; - this.minorChange = true; - this.copyLocation = COPYLOCATION_CURRENT; - this.versionNotes = ""; - this.selectedSpaceId = null; - - // remove the file upload bean from the session - FacesContext ctx = FacesContext.getCurrentInstance(); - ctx.getExternalContext().getSessionMap().remove(FileUploadBean.FILE_UPLOAD_BEAN_NAME); - } - - - // ------------------------------------------------------------------------------ - // Private data - - private static final Log LOGGER = LogFactory.getLog(CheckinCheckoutBean.class); - - /** I18N messages */ - private static final String MSG_ERROR_CHECKIN = "error_checkin"; - private static final String MSG_ERROR_CANCELCHECKOUT = "error_cancel_checkout"; - private static final String MSG_ERROR_UPDATE = "error_update"; - private static final String MSG_ERROR_CHECKOUT = "error_checkout"; - - /** constants for copy location selection */ - private static final String COPYLOCATION_CURRENT = "current"; - private static final String COPYLOCATION_OTHER = "other"; - - /** The current document */ - private Node document; - - /** The working copy of the document we are checking out */ - private Node workingDocument; - - /** Content of the document used for HTML in-line editing */ - private String documentContent; - - /** Content of the document returned from in-line editing */ - private String editorOutput; - - /** transient form and upload properties */ - private File file; - private String fileName; - private boolean keepCheckedOut = false; - private boolean minorChange = true; - private String copyLocation = COPYLOCATION_CURRENT; - private String versionNotes = ""; - private NodeRef selectedSpaceId = null; - - /** The BrowseBean to be used by the bean */ - protected BrowseBean browseBean; - - /** The NavigationBean bean reference */ - protected NavigationBean navigator; - - /** The NodeService to be used by the bean */ - protected NodeService nodeService; - - /** The VersionOperationsService to be used by the bean */ - protected CheckOutCheckInService versionOperationsService; - - /** The ContentService to be used by the bean */ - protected ContentService contentService; -} +/* + * Copyright (C) 2005 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ +package org.alfresco.web.bean; + +import java.io.File; +import java.io.Serializable; +import java.text.MessageFormat; +import java.util.HashMap; +import java.util.Map; + +import javax.faces.context.FacesContext; +import javax.faces.event.ActionEvent; +import javax.transaction.UserTransaction; + +import org.alfresco.model.ContentModel; +import org.alfresco.repo.content.MimetypeMap; +import org.alfresco.repo.version.VersionModel; +import org.alfresco.service.cmr.coci.CheckOutCheckInService; +import org.alfresco.service.cmr.repository.ChildAssociationRef; +import org.alfresco.service.cmr.repository.ContentData; +import org.alfresco.service.cmr.repository.ContentReader; +import org.alfresco.service.cmr.repository.ContentService; +import org.alfresco.service.cmr.repository.ContentWriter; +import org.alfresco.service.cmr.repository.InvalidNodeRefException; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.cmr.version.Version; +import org.alfresco.service.cmr.version.VersionType; +import org.alfresco.web.app.AlfrescoNavigationHandler; +import org.alfresco.web.app.Application; +import org.alfresco.web.app.context.UIContextService; +import org.alfresco.web.app.servlet.DownloadContentServlet; +import org.alfresco.web.bean.repository.Node; +import org.alfresco.web.bean.repository.Repository; +import org.alfresco.web.templating.OutputUtil; +import org.alfresco.web.templating.TemplatingService; +import org.alfresco.web.ui.common.Utils; +import org.alfresco.web.ui.common.component.UIActionLink; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * @author Kevin Roast + */ +public class CheckinCheckoutBean +{ + // ------------------------------------------------------------------------------ + // Bean property getters and setters + + /** + * @param navigator The NavigationBean to set. + */ + public void setNavigator(NavigationBean navigator) + { + this.navigator = navigator; + } + + /** + * @return Returns the BrowseBean. + */ + public BrowseBean getBrowseBean() + { + return this.browseBean; + } + + /** + * @param browseBean The BrowseBean to set. + */ + public void setBrowseBean(BrowseBean browseBean) + { + this.browseBean = browseBean; + } + + /** + * @return Returns the NodeService. + */ + public NodeService getNodeService() + { + return this.nodeService; + } + + /** + * @param nodeService The NodeService to set. + */ + public void setNodeService(NodeService nodeService) + { + this.nodeService = nodeService; + } + + /** + * @return Returns the VersionOperationsService. + */ + public CheckOutCheckInService getVersionOperationsService() + { + return this.versionOperationsService; + } + + /** + * @param versionOperationsService The VersionOperationsService to set. + */ + public void setVersionOperationsService(CheckOutCheckInService versionOperationsService) + { + this.versionOperationsService = versionOperationsService; + } + + /** + * @return Returns the ContentService. + */ + public ContentService getContentService() + { + return this.contentService; + } + + /** + * @param contentService The ContentService to set. + */ + public void setContentService(ContentService contentService) + { + this.contentService = contentService; + } + + /** + * @return The document node being used for the current operation + */ + public Node getDocument() + { + return this.document; + } + + /** + * @param document The document node to be used for the current operation + */ + public void setDocument(Node document) + { + this.document = document; + } + + /** + * @return Returns the working copy Document. + */ + public Node getWorkingDocument() + { + return this.workingDocument; + } + + /** + * @param workingDocument The working copy Document to set. + */ + public void setWorkingDocument(Node workingDocument) + { + this.workingDocument = workingDocument; + } + + /** + * Determines whether the document being checked in has + * the versionable aspect applied + * + * @return true if the versionable aspect is applied + */ + public boolean isVersionable() + { + return getDocument().hasAspect(ContentModel.ASPECT_VERSIONABLE); + } + + /** + * @param keepCheckedOut The keepCheckedOut to set. + */ + public void setKeepCheckedOut(boolean keepCheckedOut) + { + this.keepCheckedOut = keepCheckedOut; + } + + /** + * @return Returns the keepCheckedOut. + */ + public boolean getKeepCheckedOut() + { + return this.keepCheckedOut; + } + + /** + * @param minorChange The minorChange to set. + */ + public void setMinorChange(boolean minorChange) + { + this.minorChange = minorChange; + } + + /** + * @return Returns the minorChange flag. + */ + public boolean getMinorChange() + { + return this.minorChange; + } + + /** + * @return Returns the version history notes. + */ + public String getVersionNotes() + { + return this.versionNotes; + } + + /** + * @param versionNotes The version history notes to set. + */ + public void setVersionNotes(String versionNotes) + { + this.versionNotes = versionNotes; + } + + /** + * @return Returns the selected Space Id. + */ + public NodeRef getSelectedSpaceId() + { + return this.selectedSpaceId; + } + + /** + * @param selectedSpaceId The selected Space Id to set. + */ + public void setSelectedSpaceId(NodeRef selectedSpaceId) + { + this.selectedSpaceId = selectedSpaceId; + } + + /** + * @return Returns the copy location. Either the current or other space. + */ + public String getCopyLocation() + { + if (this.fileName != null) + { + return CheckinCheckoutBean.COPYLOCATION_OTHER; + } + else + { + return this.copyLocation; + } + } + + /** + * @param copyLocation The copy location. Either the current or other space. + */ + public void setCopyLocation(String copyLocation) + { + this.copyLocation = copyLocation; + } + + /** + * @return Returns the message to display when a file has been uploaded + */ + public String getFileUploadSuccessMsg() + { + String msg = Application.getMessage(FacesContext.getCurrentInstance(), "file_upload_success"); + return MessageFormat.format(msg, new Object[] {getFileName()}); + } + + /** + * @return Returns the name of the file + */ + public String getFileName() + { + // try and retrieve the file and filename from the file upload bean + // representing the file we previously uploaded. + FacesContext ctx = FacesContext.getCurrentInstance(); + FileUploadBean fileBean = (FileUploadBean)ctx.getExternalContext().getSessionMap(). + get(FileUploadBean.FILE_UPLOAD_BEAN_NAME); + if (fileBean != null) + { + this.file = fileBean.getFile(); + this.fileName = fileBean.getFileName(); + } + + return this.fileName; + } + + /** + * @param fileName The name of the file + */ + public void setFileName(String fileName) + { + this.fileName = fileName; + + // we also need to keep the file upload bean in sync + FacesContext ctx = FacesContext.getCurrentInstance(); + FileUploadBean fileBean = (FileUploadBean)ctx.getExternalContext().getSessionMap(). + get(FileUploadBean.FILE_UPLOAD_BEAN_NAME); + if (fileBean != null) + { + fileBean.setFileName(this.fileName); + } + } + + /** + * @return Returns the document content used for HTML in-line editing. + */ + public String getDocumentContent() + { + return this.documentContent; + } + + /** + * @param documentContent The document content for HTML in-line editing. + */ + public void setDocumentContent(String documentContent) + { + this.documentContent = documentContent; + } + + /** + * @return Returns output from the in-line editor page. + */ + public String getEditorOutput() + { + return this.editorOutput; + } + + /** + * @param editorOutput The output from the in-line editor page + */ + public void setEditorOutput(String editorOutput) + { + this.editorOutput = editorOutput; + } + + + // ------------------------------------------------------------------------------ + // Navigation action event handlers + + /** + * Action event called by all actions that need to setup a Content Document context on the + * CheckinCheckoutBean before an action page/wizard is called. The context will be a Node in + * setDocument() which can be retrieved on action pages via getDocument(). + * + * @param event ActionEvent + */ + public void setupContentAction(ActionEvent event) + { + UIActionLink link = (UIActionLink)event.getComponent(); + Map params = link.getParameterMap(); + String id = params.get("id"); + if (id != null && id.length() != 0) + { + setupContentDocument(id); + } + else + { + setDocument(null); + } + + clearUpload(); + } + + /** + * Setup a content document node context + * + * @param id GUID of the node to setup as the content document context + * + * @return The Node + */ + private Node setupContentDocument(String id) + { + if (logger.isDebugEnabled()) + logger.debug("Setup for action, setting current document to: " + id); + + Node node = null; + + try + { + // create the node ref, then our node representation + NodeRef ref = new NodeRef(Repository.getStoreRef(), id); + node = new Node(ref); + + // create content URL to the content download servlet with ID and expected filename + // the myfile part will be ignored by the servlet but gives the browser a hint + String url = DownloadContentServlet.generateDownloadURL(ref, node.getName()); + node.getProperties().put("url", url); + node.getProperties().put("workingCopy", node.hasAspect(ContentModel.ASPECT_WORKING_COPY)); + node.getProperties().put("fileType32", Utils.getFileTypeImage(node.getName(), false)); + + // remember the document + setDocument(node); + + // refresh the UI, calling this method now is fine as it basically makes sure certain + // beans clear the state - so when we finish here other beans will have been reset + UIContextService.getInstance(FacesContext.getCurrentInstance()).notifyBeans(); + } + catch (InvalidNodeRefException refErr) + { + Utils.addErrorMessage(MessageFormat.format(Application.getMessage( + FacesContext.getCurrentInstance(), Repository.ERROR_NODEREF), new Object[] {id}) ); + } + + return node; + } + + /** + * Action called upon completion of the Check Out file page + */ + public String checkoutFile() + { + String outcome = null; + + UserTransaction tx = null; + + Node node = getDocument(); + if (node != null) + { + try + { + tx = Repository.getUserTransaction(FacesContext.getCurrentInstance()); + tx.begin(); + + if (logger.isDebugEnabled()) + logger.debug("Trying to checkout content node Id: " + node.getId()); + + // checkout the node content to create a working copy + if (logger.isDebugEnabled()) + { + logger.debug("Checkout copy location: " + getCopyLocation()); + logger.debug("Selected Space Id: " + this.selectedSpaceId); + } + NodeRef workingCopyRef; + if (getCopyLocation().equals(COPYLOCATION_OTHER) && this.selectedSpaceId != null) + { + // checkout to a arbituary parent Space + NodeRef destRef = this.selectedSpaceId; + + ChildAssociationRef childAssocRef = this.nodeService.getPrimaryParent(destRef); + workingCopyRef = this.versionOperationsService.checkout(node.getNodeRef(), + destRef, ContentModel.ASSOC_CONTAINS, childAssocRef.getQName()); + } + else + { + workingCopyRef = this.versionOperationsService.checkout(node.getNodeRef()); + } + + // set the working copy Node instance + Node workingCopy = new Node(workingCopyRef); + setWorkingDocument(workingCopy); + + // create content URL to the content download servlet with ID and expected filename + // the myfile part will be ignored by the servlet but gives the browser a hint + String url = DownloadContentServlet.generateDownloadURL(workingCopyRef, workingCopy.getName()); + + workingCopy.getProperties().put("url", url); + workingCopy.getProperties().put("fileType32", Utils.getFileTypeImage(workingCopy.getName(), false)); + + // commit the transaction + tx.commit(); + + // show the page that display the checkout link + outcome = "checkoutFileLink"; + } + catch (Throwable err) + { + // rollback the transaction + try { if (tx != null) {tx.rollback();} } catch (Exception tex) {} + Utils.addErrorMessage(Application.getMessage( + FacesContext.getCurrentInstance(), MSG_ERROR_CHECKOUT) + err.getMessage(), err); + } + } + else + { + logger.warn("WARNING: checkoutFile called without a current Document!"); + } + + return outcome; + } + + /** + * Action called upon completion of the Check Out file Link download page + */ + public String checkoutFileOK() + { + String outcome = null; + + Node node = getWorkingDocument(); + if (node != null) + { + // reset the underlying node + if (this.browseBean.getDocument() != null) + { + this.browseBean.getDocument().reset(); + } + + // clean up and clear action context + clearUpload(); + setDocument(null); + setWorkingDocument(null); + + outcome = AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME; + } + else + { + logger.warn("WARNING: checkoutFileOK called without a current WorkingDocument!"); + } + + return outcome; + } + + /** + * Action called upon completion of the Edit File download page + */ + public String editFileOK() + { + String outcome = null; + + Node node = getDocument(); + if (node != null) + { + // clean up and clear action context + clearUpload(); + setDocument(null); + setWorkingDocument(null); + + outcome = AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME; + } + else + { + logger.warn("WARNING: editFileOK called without a current Document!"); + } + + return outcome; + } + + /** + * Action handler called to calculate which editing screen to display based on the mimetype + * of a document. If appropriate, the in-line editing screen will be shown. + */ + public void editFile(ActionEvent event) + { + UIActionLink link = (UIActionLink)event.getComponent(); + Map params = link.getParameterMap(); + String id = params.get("id"); + if (id != null && id.length() != 0) + { + boolean editingInline = false; + Node node = setupContentDocument(id); + + // detect the inline editing aspect to see which edit mode to use + if (node.hasAspect(ContentModel.ASPECT_INLINEEDITABLE) && + node.getProperties().get(ContentModel.PROP_EDITINLINE) != null && + ((Boolean)node.getProperties().get(ContentModel.PROP_EDITINLINE)).booleanValue() == true) + { + // retrieve the content reader for this node + ContentReader reader = getContentService().getReader(node.getNodeRef(), ContentModel.PROP_CONTENT); + if (reader != null) + { + editingInline = true; + String mimetype = reader.getMimetype(); + + // calculate which editor screen to display + if (MimetypeMap.MIMETYPE_TEXT_PLAIN.equals(mimetype) || + MimetypeMap.MIMETYPE_XML.equals(mimetype) || + MimetypeMap.MIMETYPE_TEXT_CSS.equals(mimetype) || + MimetypeMap.MIMETYPE_JAVASCRIPT.equals(mimetype)) + { + // make content available to the editing screen + setEditorOutput(reader.getContentString()); + + // navigate to appropriate screen + FacesContext fc = FacesContext.getCurrentInstance(); + this.navigator.setupDispatchContext(node); + String s = (MimetypeMap.MIMETYPE_XML.equals(mimetype) + ? "dialog:editXmlInline" + : "dialog:editTextInline"); + fc.getApplication().getNavigationHandler().handleNavigation(fc, null, s); + + } + else + { + // make content available to the editing screen + setDocumentContent(reader.getContentString()); + setEditorOutput(null); + + // navigate to appropriate screen + FacesContext fc = FacesContext.getCurrentInstance(); + this.navigator.setupDispatchContext(node); + fc.getApplication().getNavigationHandler().handleNavigation(fc, null, "dialog:editHtmlInline"); + } + } + } + + if (editingInline == false) + { + // normal downloadable document + FacesContext fc = FacesContext.getCurrentInstance(); + this.navigator.setupDispatchContext(node); + fc.getApplication().getNavigationHandler().handleNavigation(fc, null, "dialog:editFile"); + } + } + } + + /** + * Action handler called to set the content of a node from an inline editing page. + */ + public String editInlineOK() + { + String outcome = null; + + UserTransaction tx = null; + + Node node = getDocument(); + if (node != null) + { + try + { + tx = Repository.getUserTransaction(FacesContext.getCurrentInstance()); + tx.begin(); + + if (logger.isDebugEnabled()) + logger.debug("Trying to update content node Id: " + node.getId()); + + // get an updating writer that we can use to modify the content on the current node + ContentWriter writer = this.contentService.getWriter(node.getNodeRef(), ContentModel.PROP_CONTENT, true); + writer.putContent(this.editorOutput); + + // commit the transaction + tx.commit(); + + if (nodeService.getProperty(node.getNodeRef(), + TemplatingService.TT_QNAME) != null) + { + OutputUtil.regenerate(node.getNodeRef(), + this.contentService, + this.nodeService); + } + + // clean up and clear action context + clearUpload(); + setDocument(null); + setDocumentContent(null); + setEditorOutput(null); + + outcome = AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME; + } + catch (Throwable err) + { + // rollback the transaction + try { if (tx != null) {tx.rollback();} } catch (Exception tex) {} + Utils.addErrorMessage(Application.getMessage( + FacesContext.getCurrentInstance(), MSG_ERROR_UPDATE) + err.getMessage()); + } + } + else + { + logger.warn("WARNING: editInlineOK called without a current Document!"); + } + + return outcome; + } + + /** + * Action to undo the checkout of a document just checked out from the checkout screen. + */ + public String undoCheckout() + { + String outcome = null; + + Node node = getWorkingDocument(); + if (node != null) + { + try + { + // try to cancel checkout of the working copy + this.versionOperationsService.cancelCheckout(node.getNodeRef()); + + clearUpload(); + + outcome = AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME; + } + catch (Throwable err) + { + Utils.addErrorMessage(Application.getMessage( + FacesContext.getCurrentInstance(), MSG_ERROR_CANCELCHECKOUT) + err.getMessage(), err); + } + } + else + { + logger.warn("WARNING: undoCheckout called without a current WorkingDocument!"); + } + + return outcome; + } + + /** + * Action to undo the checkout of a locked document. This document may either by the original copy + * or the working copy node. Therefore calculate which it is, if the working copy is found then + * we simply cancel checkout on that document. If the original copy is found then we need to find + * the appropriate working copy and perform the action on that node. + */ + public String undoCheckoutFile() + { + String outcome = null; + + Node node = getDocument(); + if (node != null) + { + try + { + if (node.hasAspect(ContentModel.ASPECT_WORKING_COPY)) + { + this.versionOperationsService.cancelCheckout(node.getNodeRef()); + } + else if (node.hasAspect(ContentModel.ASPECT_LOCKABLE)) + { + // TODO: find the working copy for this document and cancel the checkout on it + // is this possible? as currently only the workingcopy aspect has the copyReference + // attribute - this means we cannot find out where the copy is to cancel it! + // can we construct an XPath node lookup? + throw new RuntimeException("NOT IMPLEMENTED"); + } + else + { + throw new IllegalStateException("Node supplied for undo checkout has neither Working Copy or Locked aspect!"); + } + + clearUpload(); + + outcome = AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME + AlfrescoNavigationHandler.OUTCOME_SEPARATOR + "browse"; + } + catch (Throwable err) + { + Utils.addErrorMessage(MSG_ERROR_CANCELCHECKOUT + err.getMessage(), err); + } + } + else + { + logger.warn("WARNING: undoCheckout called without a current WorkingDocument!"); + } + + return outcome; + } + + /** + * Action called upon completion of the Check In file page + */ + public String checkinFileOK() + { + String outcome = null; + + UserTransaction tx = null; + + // NOTE: for checkin the document node _is_ the working document! + Node node = getDocument(); + if (node != null && (getCopyLocation().equals(COPYLOCATION_CURRENT) || this.getFileName() != null)) + { + try + { + FacesContext context = FacesContext.getCurrentInstance(); + tx = Repository.getUserTransaction(context); + tx.begin(); + + if (logger.isDebugEnabled()) + logger.debug("Trying to checkin content node Id: " + node.getId()); + + // we can either checkin the content from the current working copy node + // which would have been previously updated by the user + String contentUrl; + if (getCopyLocation().equals(COPYLOCATION_CURRENT)) + { + ContentData contentData = (ContentData) node.getProperties().get(ContentModel.PROP_CONTENT); + contentUrl = (contentData == null ? null : contentData.getContentUrl()); + } + // or specify a specific file as the content instead + else + { + // add the content to an anonymous but permanent writer location + // we can then retrieve the URL to the content to to be set on the node during checkin + ContentWriter writer = this.contentService.getWriter(node.getNodeRef(), ContentModel.PROP_CONTENT, true); + // also update the mime type in case a different type of file is uploaded + String mimeType = Repository.getMimeTypeForFileName(context, this.fileName); + writer.setMimetype(mimeType); + writer.putContent(this.file); + contentUrl = writer.getContentUrl(); + } + + if (contentUrl == null || contentUrl.length() == 0) + { + throw new IllegalStateException("Content URL is empty for specified working copy content node!"); + } + + // add version history text to props + Map props = new HashMap(1, 1.0f); + props.put(Version.PROP_DESCRIPTION, this.versionNotes); + // set the flag for minor or major change + if (this.minorChange) + { + props.put(VersionModel.PROP_VERSION_TYPE, VersionType.MINOR); + } + else + { + props.put(VersionModel.PROP_VERSION_TYPE, VersionType.MAJOR); + } + + // perform the checkin + this.versionOperationsService.checkin(node.getNodeRef(), + props, contentUrl, this.keepCheckedOut); + + // commit the transaction + tx.commit(); + + // clear action context + setDocument(null); + clearUpload(); + + outcome = AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME + + AlfrescoNavigationHandler.OUTCOME_SEPARATOR + "browse"; + } + catch (Throwable err) + { + // rollback the transaction + try { if (tx != null) {tx.rollback();} } catch (Exception tex) {} + Utils.addErrorMessage(Application.getMessage( + FacesContext.getCurrentInstance(), MSG_ERROR_CHECKIN) + err.getMessage(), err); + } + } + else + { + logger.warn("WARNING: checkinFileOK called without a current Document!"); + } + + return outcome; + } + + /** + * Action called upon completion of the Update File page + */ + public String updateFileOK() + { + String outcome = null; + + UserTransaction tx = null; + + // NOTE: for update the document node _is_ the working document! + Node node = getDocument(); + if (node != null && this.getFileName() != null) + { + try + { + FacesContext context = FacesContext.getCurrentInstance(); + tx = Repository.getUserTransaction(context); + tx.begin(); + + if (logger.isDebugEnabled()) + logger.debug("Trying to update content node Id: " + node.getId()); + + // get an updating writer that we can use to modify the content on the current node + ContentWriter writer = this.contentService.getWriter(node.getNodeRef(), ContentModel.PROP_CONTENT, true); + + // also update the mime type in case a different type of file is uploaded + String mimeType = Repository.getMimeTypeForFileName(context, this.fileName); + writer.setMimetype(mimeType); + + writer.putContent(this.file); + + // commit the transaction + tx.commit(); + + // clear action context + setDocument(null); + clearUpload(); + + outcome = AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME; + } + catch (Throwable err) + { + // rollback the transaction + try { if (tx != null) {tx.rollback();} } catch (Exception tex) {} + Utils.addErrorMessage(Application.getMessage( + FacesContext.getCurrentInstance(), MSG_ERROR_UPDATE) + err.getMessage(), err); + } + } + else + { + logger.warn("WARNING: updateFileOK called without a current Document!"); + } + + return outcome; + } + + /** + * Deals with the cancel button being pressed on the check in file page + */ + public String cancel() + { + // reset the state + clearUpload(); + + return AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME; + } + + /** + * Clear form state and upload file bean + */ + private void clearUpload() + { + // delete the temporary file we uploaded earlier + if (this.file != null) + { + this.file.delete(); + } + + this.file = null; + this.fileName = null; + this.keepCheckedOut = false; + this.minorChange = true; + this.copyLocation = COPYLOCATION_CURRENT; + this.versionNotes = ""; + this.selectedSpaceId = null; + + // remove the file upload bean from the session + FacesContext ctx = FacesContext.getCurrentInstance(); + ctx.getExternalContext().getSessionMap().remove(FileUploadBean.FILE_UPLOAD_BEAN_NAME); + } + + + // ------------------------------------------------------------------------------ + // Private data + + private static Log logger = LogFactory.getLog(CheckinCheckoutBean.class); + + /** I18N messages */ + private static final String MSG_ERROR_CHECKIN = "error_checkin"; + private static final String MSG_ERROR_CANCELCHECKOUT = "error_cancel_checkout"; + private static final String MSG_ERROR_UPDATE = "error_update"; + private static final String MSG_ERROR_CHECKOUT = "error_checkout"; + + /** constants for copy location selection */ + private static final String COPYLOCATION_CURRENT = "current"; + private static final String COPYLOCATION_OTHER = "other"; + + /** The current document */ + private Node document; + + /** The working copy of the document we are checking out */ + private Node workingDocument; + + /** Content of the document used for HTML in-line editing */ + private String documentContent; + + /** Content of the document returned from in-line editing */ + private String editorOutput; + + /** transient form and upload properties */ + private File file; + private String fileName; + private boolean keepCheckedOut = false; + private boolean minorChange = true; + private String copyLocation = COPYLOCATION_CURRENT; + private String versionNotes = ""; + private NodeRef selectedSpaceId = null; + + /** The BrowseBean to be used by the bean */ + protected BrowseBean browseBean; + + /** The NavigationBean bean reference */ + protected NavigationBean navigator; + + /** The NodeService to be used by the bean */ + protected NodeService nodeService; + + /** The VersionOperationsService to be used by the bean */ + protected CheckOutCheckInService versionOperationsService; + + /** The ContentService to be used by the bean */ + protected ContentService contentService; +} diff --git a/source/java/org/alfresco/web/bean/content/CreateContentWizard.java b/source/java/org/alfresco/web/bean/content/CreateContentWizard.java index dd11533c0d..ca61c9a54b 100644 --- a/source/java/org/alfresco/web/bean/content/CreateContentWizard.java +++ b/source/java/org/alfresco/web/bean/content/CreateContentWizard.java @@ -53,14 +53,14 @@ import org.alfresco.web.app.servlet.FacesHelper; */ public class CreateContentWizard extends BaseContentWizard { - protected String content = null; + protected String content = null; protected String templateTypeName; - protected List createMimeTypes; - + protected List createMimeTypes; + private static final Log LOGGER = LogFactory.getLog(CreateContentWizard.class); - + // ------------------------------------------------------------------------------ // Wizard implementation @@ -69,7 +69,7 @@ public class CreateContentWizard extends BaseContentWizard throws Exception { LOGGER.debug("saving file content to " + this.fileName); - saveContent(null, this.content); + saveContent(null, this.content); if (this.templateTypeName != null) { LOGGER.debug("generating template output for " + this.templateTypeName); @@ -87,9 +87,9 @@ public class CreateContentWizard extends BaseContentWizard this.contentService, this.nodeService); } - - // return the default outcome - return outcome; + + // return the default outcome + return outcome; } @Override @@ -162,7 +162,7 @@ public class CreateContentWizard extends BaseContentWizard { this.content = content; } - + public List getCreateTemplateTypes() { Collection ttl = TemplatingService.getInstance().getTemplateTypes(); @@ -225,7 +225,7 @@ public class CreateContentWizard extends BaseContentWizard return this.createMimeTypes; } - + public String getTemplateTypeName() { return this.templateTypeName; diff --git a/source/java/org/alfresco/web/bean/dashboard/DashboardManager.java b/source/java/org/alfresco/web/bean/dashboard/DashboardManager.java index bea7e5f967..29e9f1de4b 100644 --- a/source/java/org/alfresco/web/bean/dashboard/DashboardManager.java +++ b/source/java/org/alfresco/web/bean/dashboard/DashboardManager.java @@ -42,8 +42,9 @@ public class DashboardManager private static Log logger = LogFactory.getLog(DashboardManager.class); private static final String PREF_DASHBOARD = "dashboard"; - static final String LAYOUT_DEFAULT = "default"; - static final String DASHLET_DEFAULT = "getting-started"; + private static final String LAYOUT_DEFAULT = "default"; + private static final String DASHLET_STARTEDDEFAULT = "getting-started"; + private static final String DASHLET_TASKSDEFAULT = "tasks-todo"; private static final String JSP_DUMMY = "/jsp/dashboards/dummy.jsp"; @@ -150,13 +151,22 @@ public class DashboardManager { Page page = new Page("default", layout); Column defaultColumn = new Column(); - DashletDefinition dashlet = config.getDashletDefinition(DASHLET_DEFAULT); + + // add the default dashlet(s) to the column + DashletDefinition dashlet = config.getDashletDefinition(DASHLET_STARTEDDEFAULT); if (dashlet != null) { defaultColumn.addDashlet(dashlet); - page.addColumn(defaultColumn); - pageConfig.addPage(page); } + dashlet = config.getDashletDefinition(DASHLET_TASKSDEFAULT); + if (dashlet != null) + { + defaultColumn.addDashlet(dashlet); + } + + // add the column to the page and we are done + page.addColumn(defaultColumn); + pageConfig.addPage(page); } } diff --git a/source/java/org/alfresco/web/bean/workflow/StartWorkflowWizard.java b/source/java/org/alfresco/web/bean/workflow/StartWorkflowWizard.java index 3e79a173dc..c8e5d0a086 100644 --- a/source/java/org/alfresco/web/bean/workflow/StartWorkflowWizard.java +++ b/source/java/org/alfresco/web/bean/workflow/StartWorkflowWizard.java @@ -447,6 +447,17 @@ public class StartWorkflowWizard extends BaseWizardBean new String[] {workflowName}); } + /** + * Determines whether there are any workflows to start + * @return + */ + public boolean getHasStartableWorkflows() + { + // get the list of startable workflow, this will intialise the list if necessary + List workflows = getStartableWorkflows(); + return (workflows.size() > 0); + } + /** * Returns a list of workflows that can be started. * diff --git a/source/java/org/alfresco/web/ui/common/renderer/ImagePickerRadioRenderer.java b/source/java/org/alfresco/web/ui/common/renderer/ImagePickerRadioRenderer.java index e3212a7212..68fc6bb62f 100644 --- a/source/java/org/alfresco/web/ui/common/renderer/ImagePickerRadioRenderer.java +++ b/source/java/org/alfresco/web/ui/common/renderer/ImagePickerRadioRenderer.java @@ -25,6 +25,7 @@ import javax.faces.component.UIComponent; import javax.faces.component.UIInput; import javax.faces.context.FacesContext; import javax.faces.context.ResponseWriter; +import javax.faces.el.PropertyNotFoundException; import org.alfresco.config.Config; import org.alfresco.config.ConfigElement; @@ -162,34 +163,46 @@ public class ImagePickerRadioRenderer extends BaseRenderer } else { - // get the child components - for (Iterator i = imagePicker.getChildren().iterator(); i.hasNext(); /**/) + try { - UIComponent child = (UIComponent)i.next(); - if (child instanceof UIListItems) + // get the child components + for (Iterator i = imagePicker.getChildren().iterator(); i.hasNext(); /**/) { - // get the value of the list items component and iterate - // through it's collection - Object listItems = ((UIListItems)child).getValue(); - if (listItems instanceof Collection) + UIComponent child = (UIComponent)i.next(); + if (child instanceof UIListItems) { - Iterator iter = ((Collection)listItems).iterator(); - while (iter.hasNext()) + // get the value of the list items component and iterate + // through it's collection + Object listItems = ((UIListItems)child).getValue(); + if (listItems instanceof Collection) { - UIListItem item = (UIListItem)iter.next(); - if (item.isRendered()) + Iterator iter = ((Collection)listItems).iterator(); + while (iter.hasNext()) { - renderItem(context, out, imagePicker, item, onclick); + UIListItem item = (UIListItem)iter.next(); + if (item.isRendered()) + { + renderItem(context, out, imagePicker, item, onclick); + } } } } + else if (child instanceof UIListItem && child.isRendered() == true) + { + // found a valid UIListItem child to render + UIListItem item = (UIListItem)child; + renderItem(context, out, imagePicker, item, onclick); + } } - else if (child instanceof UIListItem && child.isRendered() == true) - { - // found a valid UIListItem child to render - UIListItem item = (UIListItem)child; - renderItem(context, out, imagePicker, item, onclick); - } + } + catch (PropertyNotFoundException pnfe) + { + // handle the scenario where the bean does not have the + // method specified in the value binding expression + if (logger.isWarnEnabled()) + logger.warn("Failed to retrieve icons: " + pnfe.toString()); + + out.write(Application.getMessage(context, "no_icons_found")); } } diff --git a/source/web/WEB-INF/faces-config-beans.xml b/source/web/WEB-INF/faces-config-beans.xml index 67c90a40f8..f5b4cd795f 100644 --- a/source/web/WEB-INF/faces-config-beans.xml +++ b/source/web/WEB-INF/faces-config-beans.xml @@ -1466,6 +1466,10 @@ fileFolderService #{FileFolderService} + + searchService + #{SearchService} + navigator #{NavigationBean} @@ -1780,43 +1784,6 @@ - - - The bean that backs up the Delete Post Dialog - - DeletePostDialog - org.alfresco.web.bean.forums.DeletePostDialog - session - - nodeService - #{NodeService} - - - fileFolderService - #{FileFolderService} - - - searchService - #{SearchService} - - - navigator - #{NavigationBean} - - - browseBean - #{BrowseBean} - - - dictionaryService - #{DictionaryService} - - - namespaceService - #{NamespaceService} - - - The bean that holds state for the Manage Deleted Items screen. @@ -1837,8 +1804,8 @@ #{SearchService} - namespaceService - #{NamespaceService} + dictionaryService + #{DictionaryService} @@ -2352,7 +2319,7 @@ #{ContentService} - + Bean that returns information on a node diff --git a/source/web/WEB-INF/faces-config-navigation.xml b/source/web/WEB-INF/faces-config-navigation.xml index 60e54eee7a..94494c409a 100644 --- a/source/web/WEB-INF/faces-config-navigation.xml +++ b/source/web/WEB-INF/faces-config-navigation.xml @@ -1,942 +1,910 @@ - - - - - - - - - - The decision rule used by the NavigationHandler to - determine which view must be displayed after the - current view, login.jsp is processed. - - /jsp/login.jsp - - - Indicates to the NavigationHandler that the browse.jsp - view must be displayed if the Action referenced by a - UICommand component on the login.jsp view returns - the outcome "success". - - success - /jsp/browse/browse.jsp - - - - - - /jsp/* - - browse - /jsp/browse/browse.jsp - - - myalfresco - /jsp/dashboards/container.jsp - - - about - /jsp/dialog/about.jsp - - - - - - /jsp/* - - showDocDetails - /jsp/dialog/document-details.jsp - - - showSpaceDetails - /jsp/dialog/space-details.jsp - - - dashboard - /jsp/browse/dashboard.jsp - - - addContent - /jsp/content/add-content-dialog.jsp - - - - - - /jsp/* - - advSearch - /jsp/dialog/advanced-search.jsp - - - - - - /jsp/* - - logout - /jsp/login.jsp - - - relogin - /jsp/relogin.jsp - - - - - - /jsp/* - - adminConsole - /jsp/admin/admin-console.jsp - - - userConsole - /jsp/users/user-console.jsp - - - - - - /jsp/browse/browse.jsp - - addContent - /jsp/content/add-content-dialog.jsp - - - - checkoutFile - /jsp/dialog/checkout-file.jsp - - - checkinFile - /jsp/dialog/checkin-file.jsp - - - undoCheckoutFile - /jsp/dialog/undocheckout-file.jsp - - - updateFile - /jsp/dialog/update-file.jsp - - - editFile - /jsp/dialog/edit-file.jsp - - - editHtmlInline - /jsp/dialog/edit-html-inline.jsp - - - editTextInline - /jsp/dialog/edit-text-inline.jsp - - - editXmlInline - /jsp/dialog/edit-xml-inline.jsp - - - manageInvitedUsers - /jsp/roles/manage-invited-users.jsp - - - manageContentUsers - /jsp/roles/manage-content-users.jsp - - - manageRules - /jsp/dialog/rules.jsp - - - previewContent - /jsp/dialog/preview-file.jsp - - - previewSpace - /jsp/dialog/preview-space.jsp - - - startDiscussion - /jsp/forums/create-topic.jsp - - - showForum - /jsp/forums/forum.jsp - - - showTopic - /jsp/forums/topic.jsp - - - saveNewSearch - /jsp/dialog/save-search.jsp - - - saveEditSearch - /jsp/dialog/edit-search.jsp - - - manageDeletedItems - /jsp/trashcan/trash-list.jsp - - - - - /jsp/content/add-content-dialog.jsp - - cancel - /jsp/browse/browse.jsp - - - - - - /jsp/admin/admin-console.jsp - - manageCategories - /jsp/categories/categories.jsp - - - manageUsers - /jsp/users/users.jsp - - - manageGroups - /jsp/groups/groups.jsp - - - showSystemInfo - /jsp/dialog/system-info.jsp - - - showNodeBrowser - /jsp/admin/store-browser.jsp - - - import - /jsp/dialog/import.jsp - - - export - /jsp/dialog/export.jsp - - - - - /jsp/dialog/edit-file.jsp - - checkoutFile - /jsp/dialog/checkout-file.jsp - - - - - /jsp/dialog/edit-text-inline.jsp - - checkoutFile - /jsp/dialog/checkout-file.jsp - - - - - /jsp/dialog/edit-html-inline.jsp - - checkoutFile - /jsp/dialog/checkout-file.jsp - - - - - /jsp/dialog/edit-xml-inline.jsp - - checkoutFile - /jsp/dialog/checkout-file.jsp - - - - - /jsp/dialog/checkout-file.jsp - - checkoutFileLink - /jsp/dialog/checkout-file-link.jsp - - - - - /jsp/dialog/space-details.jsp - - manageInvitedUsers - /jsp/roles/manage-invited-users.jsp - - - manageRules - /jsp/dialog/rules.jsp - - - import - /jsp/dialog/import.jsp - - - export - /jsp/dialog/export.jsp - - - applyTemplate - /jsp/dialog/apply-space-template.jsp - - - applyRSSTemplate - /jsp/dialog/apply-rss-template.jsp - - - previewSpace - /jsp/dialog/preview-space.jsp - - - showForum - /jsp/forums/forum.jsp - - - editCategories - /jsp/dialog/edit-space-category.jsp - - - - - /jsp/dialog/apply-rss-template.jsp - - manageInvitedUsers - /jsp/roles/manage-invited-users.jsp - - - - - /jsp/dialog/document-details.jsp - - checkoutFile - /jsp/dialog/checkout-file.jsp - - - checkinFile - /jsp/dialog/checkin-file.jsp - - - undoCheckoutFile - /jsp/dialog/undocheckout-file.jsp - - - updateFile - /jsp/dialog/update-file.jsp - - - editFile - /jsp/dialog/edit-file.jsp - - - editHtmlInline - /jsp/dialog/edit-html-inline.jsp - - - editTextInline - /jsp/dialog/edit-text-inline.jsp - - - editXmlInline - /jsp/dialog/edit-xml-inline.jsp - - - editSimpleWorkflow - /jsp/dialog/edit-simple-workflow.jsp - - - editCategories - /jsp/dialog/edit-category.jsp - - - previewContent - /jsp/dialog/preview-file.jsp - - - showForum - /jsp/forums/forum.jsp - - - manageContentUsers - /jsp/roles/manage-content-users.jsp - - - applyTemplate - /jsp/dialog/apply-doc-template.jsp - - - - - /jsp/dialog/edit-simple-workflow.jsp - - cancel - /jsp/dialog/document-details.jsp - - - finish - /jsp/dialog/document-details.jsp - - - - - /jsp/dialog/edit-category.jsp - - cancel - /jsp/dialog/document-details.jsp - - - finish - /jsp/dialog/document-details.jsp - - - - - /jsp/dialog/edit-space-category.jsp - - cancel - /jsp/dialog/space-details.jsp - - - finish - /jsp/dialog/space-details.jsp - - - - - /jsp/dialog/rules.jsp - - deleteRule - /jsp/dialog/delete-rule.jsp - - - - - /jsp/dialog/delete-rule.jsp - - manageRules - /jsp/dialog/rules.jsp - - - cancel - /jsp/dialog/rules.jsp - - - browse - /jsp/dialog/rules.jsp - - - - - - /jsp/dialog/filelink-details.jsp - - editLinkProperties - /jsp/dialog/edit-link-properties.jsp - - - manageContentUsers - /jsp/roles/manage-content-users.jsp - - - - - - /jsp/dialog/spacelink-details.jsp - - editLinkProperties - /jsp/dialog/edit-link-properties.jsp - - - manageContentUsers - /jsp/roles/manage-content-users.jsp - - - - - - /jsp/dialog/edit-link-properties.jsp - - cancelEdit - /jsp/dialog/filelink-details.jsp - - - finishEdit - /jsp/dialog/filelink-details.jsp - - - - - - /jsp/roles/manage-invited-users.jsp - - inviteUsers - /jsp/wizard/invite-users/invite.jsp - - - editRoles - /jsp/roles/edit-user-roles.jsp - - - removeUser - /jsp/roles/remove-invited-user.jsp - - - - - /jsp/roles/edit-user-roles.jsp - - cancel - /jsp/roles/manage-invited-users.jsp - - - finish - /jsp/roles/manage-invited-users.jsp - - - - - /jsp/roles/remove-invited-user.jsp - - cancel - /jsp/roles/manage-invited-users.jsp - - - finish - /jsp/roles/manage-invited-users.jsp - - - - - /jsp/roles/manage-content-users.jsp - - inviteUsers - /jsp/wizard/invite-content-users/invite.jsp - - - editRoles - /jsp/roles/edit-content-user-roles.jsp - - - removeUser - /jsp/roles/remove-content-user.jsp - - - - - /jsp/roles/edit-content-user-roles.jsp - - cancel - /jsp/roles/manage-content-users.jsp - - - finish - /jsp/roles/manage-content-users.jsp - - - - - /jsp/roles/remove-content-user.jsp - - cancel - /jsp/roles/manage-content-users.jsp - - - finish - /jsp/roles/manage-content-users.jsp - - - - - - /jsp/wizard/invite-users/* - - invite - /jsp/wizard/invite-users/invite.jsp - - - notify - /jsp/wizard/invite-users/notify.jsp - - - cancel - /jsp/roles/manage-invited-users.jsp - - - finish - /jsp/roles/manage-invited-users.jsp - - - - - - /jsp/wizard/invite-content-users/* - - invite - /jsp/wizard/invite-content-users/invite.jsp - - - notify - /jsp/wizard/invite-content-users/notify.jsp - - - cancel - /jsp/roles/manage-content-users.jsp - - - finish - /jsp/roles/manage-content-users.jsp - - - - - - /jsp/users/* - - manageUsers - /jsp/users/users.jsp - - - cancel - /jsp/users/users.jsp - - - - - /jsp/users/users.jsp - - createUser - /jsp/wizard/new-user/person-properties.jsp - - - editUser - /jsp/wizard/new-user/person-properties.jsp - - - deleteUser - /jsp/users/delete-user.jsp - - - changePassword - /jsp/users/change-password.jsp - - - - - - /jsp/users/user-console.jsp - - changePassword - /jsp/users/change-my-password.jsp - - - editUserDetails - /jsp/users/edit-user-details.jsp - - - - - - /jsp/wizard/new-user/* - - cancel - /jsp/users/users.jsp - - - finish - /jsp/users/users.jsp - - - person-properties - /jsp/wizard/new-user/person-properties.jsp - - - user-properties - /jsp/wizard/new-user/user-properties.jsp - - - summary - /jsp/wizard/new-user/summary.jsp - - - - - - /jsp/groups/* - - newGroup - /jsp/groups/new-group.jsp - - - deleteGroup - /jsp/groups/delete-group.jsp - - - addUser - /jsp/groups/add-user.jsp - - - deleteUser - /jsp/groups/delete-user.jsp - - - finish - /jsp/groups/groups.jsp - - - cancel - /jsp/groups/groups.jsp - - - - - - /jsp/categories/* - - addCategory - /jsp/categories/new-category.jsp - - - editCategory - /jsp/categories/edit-category.jsp - - - deleteCategory - /jsp/categories/delete-category.jsp - - - finish - /jsp/categories/categories.jsp - - - cancel - /jsp/categories/categories.jsp - - - - - - /jsp/wizard/* - - cancel - /jsp/browse/browse.jsp - - - finish - /jsp/browse/browse.jsp - - - - - - /jsp/admin/* - - #{AdminNodeBrowseBean.selectStores} - success - /jsp/admin/store-browser.jsp - - - nodeBrowser - /jsp/admin/node-browser.jsp - - - - - /jsp/admin/store-browser.jsp - - #{AdminNodeBrowseBean.selectStore} - success - /jsp/admin/node-browser.jsp - - - - - /jsp/admin/node-browser.jsp - - #{AdminNodeBrowseBean.selectChild} - success - /jsp/admin/node-browser.jsp - - - #{AdminNodeBrowseBean.selectPrimaryPath} - success - /jsp/admin/node-browser.jsp - - - #{AdminNodeBrowseBean.selectPrimaryParent} - success - /jsp/admin/node-browser.jsp - - - #{AdminNodeBrowseBean.selectParent} - success - /jsp/admin/node-browser.jsp - - - #{AdminNodeBrowseBean.selectToNode} - success - /jsp/admin/node-browser.jsp - - - #{AdminNodeBrowseBean.selectNodeProperty} - success - /jsp/admin/node-browser.jsp - - - #{AdminNodeBrowseBean.submitSearch} - error - /jsp/admin/node-browser.jsp - - - #{AdminNodeBrowseBean.submitSearch} - node - /jsp/admin/node-browser.jsp - - - #{AdminNodeBrowseBean.submitSearch} - search - /jsp/admin/search-results.jsp - - - - - /jsp/admin/search-results.jsp - - #{AdminNodeBrowseBean.selectResultNode} - success - /jsp/admin/node-browser.jsp - - - - - - /jsp/forums/* - - - - showForumsDetails - /jsp/forums/forums-details.jsp - - - showForumDetails - /jsp/forums/forum-details.jsp - - - showTopicDetails - /jsp/forums/topic-details.jsp - - - manageInvitedUsers - /jsp/roles/manage-invited-users.jsp - - - import - /jsp/dialog/import.jsp - - - export - /jsp/dialog/export.jsp - - - - - - /jsp/trashcan/* - - deleteItem - /jsp/trashcan/delete-item.jsp - - - recoverItem - /jsp/trashcan/recover-item.jsp - - - recoverAllItems - /jsp/trashcan/recover-all.jsp - - - deleteAllItems - /jsp/trashcan/delete-all.jsp - - - recoverListedItems - /jsp/trashcan/recover-listed.jsp - - - deleteListedItems - /jsp/trashcan/delete-listed.jsp - - - itemDetails - /jsp/trashcan/item-details.jsp - - - recoveryReport - /jsp/trashcan/recovery-report.jsp - - - - - /jsp/dialog/container.jsp - - - - forumsDeleted - /jsp/forums/forums.jsp - - - forumDeleted - /jsp/forums/forums.jsp - - - topicDeleted - /jsp/forums/forum.jsp - - - - - - checkoutFile - /jsp/dialog/checkout-file.jsp - - - checkinFile - /jsp/dialog/checkin-file.jsp - - - undoCheckoutFile - /jsp/dialog/undocheckout-file.jsp - - - updateFile - /jsp/dialog/update-file.jsp - - - editFile - /jsp/dialog/edit-file.jsp - - - editHtmlInline - /jsp/dialog/edit-html-inline.jsp - - - editTextInline - /jsp/dialog/edit-text-inline.jsp - - - itemDetails - /jsp/trashcan/item-details.jsp - - - recoveryReport - /jsp/trashcan/recovery-report.jsp - - - - + + + + + + + + + + The decision rule used by the NavigationHandler to + determine which view must be displayed after the + current view, login.jsp is processed. + + /jsp/login.jsp + + + Indicates to the NavigationHandler that the browse.jsp + view must be displayed if the Action referenced by a + UICommand component on the login.jsp view returns + the outcome "success". + + success + /jsp/browse/browse.jsp + + + + + + /jsp/* + + browse + /jsp/browse/browse.jsp + + + myalfresco + /jsp/dashboards/container.jsp + + + about + /jsp/dialog/about.jsp + + + + + + /jsp/* + + showDocDetails + /jsp/dialog/document-details.jsp + + + showSpaceDetails + /jsp/dialog/space-details.jsp + + + dashboard + /jsp/browse/dashboard.jsp + + + addContent + /jsp/content/add-content-dialog.jsp + + + + + + /jsp/* + + advSearch + /jsp/dialog/advanced-search.jsp + + + + + + /jsp/* + + logout + /jsp/login.jsp + + + relogin + /jsp/relogin.jsp + + + + + + /jsp/* + + adminConsole + /jsp/admin/admin-console.jsp + + + userConsole + /jsp/users/user-console.jsp + + + + + + /jsp/* + + addContent + /jsp/content/add-content-dialog.jsp + + + + checkoutFile + /jsp/dialog/checkout-file.jsp + + + checkinFile + /jsp/dialog/checkin-file.jsp + + + undoCheckoutFile + /jsp/dialog/undocheckout-file.jsp + + + updateFile + /jsp/dialog/update-file.jsp + + + editFile + /jsp/dialog/edit-file.jsp + + + editHtmlInline + /jsp/dialog/edit-html-inline.jsp + + + editTextInline + /jsp/dialog/edit-text-inline.jsp + + + + + + /jsp/browse/browse.jsp + + + + editXmlInline + /jsp/dialog/edit-xml-inline.jsp + + + manageInvitedUsers + /jsp/roles/manage-invited-users.jsp + + + manageContentUsers + /jsp/roles/manage-content-users.jsp + + + manageRules + /jsp/dialog/rules.jsp + + + previewContent + /jsp/dialog/preview-file.jsp + + + previewSpace + /jsp/dialog/preview-space.jsp + + + startDiscussion + /jsp/forums/create-topic.jsp + + + showForum + /jsp/forums/forum.jsp + + + showTopic + /jsp/forums/topic.jsp + + + saveNewSearch + /jsp/dialog/save-search.jsp + + + saveEditSearch + /jsp/dialog/edit-search.jsp + + + manageDeletedItems + /jsp/trashcan/trash-list.jsp + + + + + /jsp/content/add-content-dialog.jsp + + cancel + /jsp/browse/browse.jsp + + + + + + /jsp/admin/admin-console.jsp + + manageCategories + /jsp/categories/categories.jsp + + + manageUsers + /jsp/users/users.jsp + + + manageGroups + /jsp/groups/groups.jsp + + + showSystemInfo + /jsp/dialog/system-info.jsp + + + showNodeBrowser + /jsp/admin/store-browser.jsp + + + import + /jsp/dialog/import.jsp + + + export + /jsp/dialog/export.jsp + + + + + /jsp/dialog/edit-file.jsp + + checkoutFile + /jsp/dialog/checkout-file.jsp + + + + + /jsp/dialog/edit-text-inline.jsp + + checkoutFile + /jsp/dialog/checkout-file.jsp + + + + + /jsp/dialog/edit-html-inline.jsp + + checkoutFile + /jsp/dialog/checkout-file.jsp + + + + + /jsp/dialog/edit-xml-inline.jsp + + checkoutFile + /jsp/dialog/checkout-file.jsp + + + + + /jsp/dialog/checkout-file.jsp + + checkoutFileLink + /jsp/dialog/checkout-file-link.jsp + + + + + /jsp/dialog/space-details.jsp + + manageInvitedUsers + /jsp/roles/manage-invited-users.jsp + + + manageRules + /jsp/dialog/rules.jsp + + + import + /jsp/dialog/import.jsp + + + export + /jsp/dialog/export.jsp + + + applyTemplate + /jsp/dialog/apply-space-template.jsp + + + applyRSSTemplate + /jsp/dialog/apply-rss-template.jsp + + + previewSpace + /jsp/dialog/preview-space.jsp + + + showForum + /jsp/forums/forum.jsp + + + editCategories + /jsp/dialog/edit-space-category.jsp + + + + + /jsp/dialog/apply-rss-template.jsp + + manageInvitedUsers + /jsp/roles/manage-invited-users.jsp + + + + + /jsp/dialog/document-details.jsp + + checkoutFile + /jsp/dialog/checkout-file.jsp + + + checkinFile + /jsp/dialog/checkin-file.jsp + + + undoCheckoutFile + /jsp/dialog/undocheckout-file.jsp + + + updateFile + /jsp/dialog/update-file.jsp + + + editFile + /jsp/dialog/edit-file.jsp + + + editHtmlInline + /jsp/dialog/edit-html-inline.jsp + + + editTextInline + /jsp/dialog/edit-text-inline.jsp + + + editXmlInline + /jsp/dialog/edit-xml-inline.jsp + + + editSimpleWorkflow + /jsp/dialog/edit-simple-workflow.jsp + + + editCategories + /jsp/dialog/edit-category.jsp + + + previewContent + /jsp/dialog/preview-file.jsp + + + showForum + /jsp/forums/forum.jsp + + + manageContentUsers + /jsp/roles/manage-content-users.jsp + + + applyTemplate + /jsp/dialog/apply-doc-template.jsp + + + + + /jsp/dialog/edit-simple-workflow.jsp + + cancel + /jsp/dialog/document-details.jsp + + + finish + /jsp/dialog/document-details.jsp + + + + + /jsp/dialog/edit-category.jsp + + cancel + /jsp/dialog/document-details.jsp + + + finish + /jsp/dialog/document-details.jsp + + + + + /jsp/dialog/edit-space-category.jsp + + cancel + /jsp/dialog/space-details.jsp + + + finish + /jsp/dialog/space-details.jsp + + + + + /jsp/dialog/rules.jsp + + deleteRule + /jsp/dialog/delete-rule.jsp + + + + + /jsp/dialog/delete-rule.jsp + + manageRules + /jsp/dialog/rules.jsp + + + cancel + /jsp/dialog/rules.jsp + + + browse + /jsp/dialog/rules.jsp + + + + + + /jsp/dialog/filelink-details.jsp + + editLinkProperties + /jsp/dialog/edit-link-properties.jsp + + + manageContentUsers + /jsp/roles/manage-content-users.jsp + + + + + + /jsp/dialog/spacelink-details.jsp + + editLinkProperties + /jsp/dialog/edit-link-properties.jsp + + + manageContentUsers + /jsp/roles/manage-content-users.jsp + + + + + + /jsp/dialog/edit-link-properties.jsp + + cancelEdit + /jsp/dialog/filelink-details.jsp + + + finishEdit + /jsp/dialog/filelink-details.jsp + + + + + + /jsp/roles/manage-invited-users.jsp + + inviteUsers + /jsp/wizard/invite-users/invite.jsp + + + editRoles + /jsp/roles/edit-user-roles.jsp + + + removeUser + /jsp/roles/remove-invited-user.jsp + + + + + /jsp/roles/edit-user-roles.jsp + + cancel + /jsp/roles/manage-invited-users.jsp + + + finish + /jsp/roles/manage-invited-users.jsp + + + + + /jsp/roles/remove-invited-user.jsp + + cancel + /jsp/roles/manage-invited-users.jsp + + + finish + /jsp/roles/manage-invited-users.jsp + + + + + /jsp/roles/manage-content-users.jsp + + inviteUsers + /jsp/wizard/invite-content-users/invite.jsp + + + editRoles + /jsp/roles/edit-content-user-roles.jsp + + + removeUser + /jsp/roles/remove-content-user.jsp + + + + + /jsp/roles/edit-content-user-roles.jsp + + cancel + /jsp/roles/manage-content-users.jsp + + + finish + /jsp/roles/manage-content-users.jsp + + + + + /jsp/roles/remove-content-user.jsp + + cancel + /jsp/roles/manage-content-users.jsp + + + finish + /jsp/roles/manage-content-users.jsp + + + + + + /jsp/wizard/invite-users/* + + invite + /jsp/wizard/invite-users/invite.jsp + + + notify + /jsp/wizard/invite-users/notify.jsp + + + cancel + /jsp/roles/manage-invited-users.jsp + + + finish + /jsp/roles/manage-invited-users.jsp + + + + + + /jsp/wizard/invite-content-users/* + + invite + /jsp/wizard/invite-content-users/invite.jsp + + + notify + /jsp/wizard/invite-content-users/notify.jsp + + + cancel + /jsp/roles/manage-content-users.jsp + + + finish + /jsp/roles/manage-content-users.jsp + + + + + + /jsp/users/* + + manageUsers + /jsp/users/users.jsp + + + cancel + /jsp/users/users.jsp + + + + + /jsp/users/users.jsp + + createUser + /jsp/wizard/new-user/person-properties.jsp + + + editUser + /jsp/wizard/new-user/person-properties.jsp + + + deleteUser + /jsp/users/delete-user.jsp + + + changePassword + /jsp/users/change-password.jsp + + + + + + /jsp/users/user-console.jsp + + changePassword + /jsp/users/change-my-password.jsp + + + editUserDetails + /jsp/users/edit-user-details.jsp + + + + + + /jsp/wizard/new-user/* + + cancel + /jsp/users/users.jsp + + + finish + /jsp/users/users.jsp + + + person-properties + /jsp/wizard/new-user/person-properties.jsp + + + user-properties + /jsp/wizard/new-user/user-properties.jsp + + + summary + /jsp/wizard/new-user/summary.jsp + + + + + + /jsp/groups/* + + newGroup + /jsp/groups/new-group.jsp + + + deleteGroup + /jsp/groups/delete-group.jsp + + + addUser + /jsp/groups/add-user.jsp + + + deleteUser + /jsp/groups/delete-user.jsp + + + finish + /jsp/groups/groups.jsp + + + cancel + /jsp/groups/groups.jsp + + + + + + /jsp/categories/* + + addCategory + /jsp/categories/new-category.jsp + + + editCategory + /jsp/categories/edit-category.jsp + + + deleteCategory + /jsp/categories/delete-category.jsp + + + finish + /jsp/categories/categories.jsp + + + cancel + /jsp/categories/categories.jsp + + + + + + /jsp/wizard/* + + cancel + /jsp/browse/browse.jsp + + + finish + /jsp/browse/browse.jsp + + + + + + /jsp/admin/* + + #{AdminNodeBrowseBean.selectStores} + success + /jsp/admin/store-browser.jsp + + + nodeBrowser + /jsp/admin/node-browser.jsp + + + + + /jsp/admin/store-browser.jsp + + #{AdminNodeBrowseBean.selectStore} + success + /jsp/admin/node-browser.jsp + + + + + /jsp/admin/node-browser.jsp + + #{AdminNodeBrowseBean.selectChild} + success + /jsp/admin/node-browser.jsp + + + #{AdminNodeBrowseBean.selectPrimaryPath} + success + /jsp/admin/node-browser.jsp + + + #{AdminNodeBrowseBean.selectPrimaryParent} + success + /jsp/admin/node-browser.jsp + + + #{AdminNodeBrowseBean.selectParent} + success + /jsp/admin/node-browser.jsp + + + #{AdminNodeBrowseBean.selectToNode} + success + /jsp/admin/node-browser.jsp + + + #{AdminNodeBrowseBean.selectNodeProperty} + success + /jsp/admin/node-browser.jsp + + + #{AdminNodeBrowseBean.submitSearch} + error + /jsp/admin/node-browser.jsp + + + #{AdminNodeBrowseBean.submitSearch} + node + /jsp/admin/node-browser.jsp + + + #{AdminNodeBrowseBean.submitSearch} + search + /jsp/admin/search-results.jsp + + + + + /jsp/admin/search-results.jsp + + #{AdminNodeBrowseBean.selectResultNode} + success + /jsp/admin/node-browser.jsp + + + + + + /jsp/forums/* + + + + showForumsDetails + /jsp/forums/forums-details.jsp + + + showForumDetails + /jsp/forums/forum-details.jsp + + + showTopicDetails + /jsp/forums/topic-details.jsp + + + manageInvitedUsers + /jsp/roles/manage-invited-users.jsp + + + import + /jsp/dialog/import.jsp + + + export + /jsp/dialog/export.jsp + + + + + + /jsp/trashcan/* + + deleteItem + /jsp/trashcan/delete-item.jsp + + + recoverItem + /jsp/trashcan/recover-item.jsp + + + recoverAllItems + /jsp/trashcan/recover-all.jsp + + + deleteAllItems + /jsp/trashcan/delete-all.jsp + + + recoverListedItems + /jsp/trashcan/recover-listed.jsp + + + deleteListedItems + /jsp/trashcan/delete-listed.jsp + + + itemDetails + /jsp/trashcan/item-details.jsp + + + recoveryReport + /jsp/trashcan/recovery-report.jsp + + + + + /jsp/dialog/container.jsp + + + + forumsDeleted + /jsp/forums/forums.jsp + + + forumDeleted + /jsp/forums/forums.jsp + + + topicDeleted + /jsp/forums/forum.jsp + + + + diff --git a/source/web/css/main.css b/source/web/css/main.css index 9e3053357c..2a6e4c1746 100644 --- a/source/web/css/main.css +++ b/source/web/css/main.css @@ -529,6 +529,13 @@ a.topToolbarLinkHighlight, a.topToolbarLinkHighlight:link, a.topToolbarLinkHighl border-color: #AAAAAA; } +.workflowSelection +{ + border: 1px solid #676767; + background-color: #efefef; + padding: 6px 12px 12px 6px; +} + .workflowSummary { margin-left: 6px; diff --git a/source/web/images/logo/alfresco_enterprise.gif b/source/web/images/logo/alfresco_enterprise.gif deleted file mode 100644 index f1b8240c8d..0000000000 Binary files a/source/web/images/logo/alfresco_enterprise.gif and /dev/null differ diff --git a/source/web/jsp/browse/browse.jsp b/source/web/jsp/browse/browse.jsp index 4314fc5948..94cc90a480 100644 --- a/source/web/jsp/browse/browse.jsp +++ b/source/web/jsp/browse/browse.jsp @@ -202,6 +202,21 @@ + <%-- Custom Template View --%> + + + + + + + + + + + + <%-- Details - Spaces --%> @@ -218,7 +233,8 @@ + label="#{msg.browse_spaces}" progressive="true" facetsId="spaces-panel-facets" + expanded='#{BrowseBean.panels["spaces-panel"]}' expandedActionListener="#{BrowseBean.expandPanel}"> <%-- Spaces List --%> + label="#{msg.browse_content}" progressive="true" facetsId="content-panel-facets" + expanded='#{BrowseBean.panels["content-panel"]}' expandedActionListener="#{BrowseBean.expandPanel}"> <%-- Content list --%> - - + +   @@ -46,8 +46,8 @@ - - + + <%-- note this component ID is referenced in DashboardWizard --%> @@ -55,22 +55,22 @@ - + - + - + <%-- note this component ID is referenced in DashboardWizard --%> - +
- +
diff --git a/source/web/jsp/rules/details.jsp b/source/web/jsp/rules/details.jsp index 1f03e9e4e1..34996610a0 100644 --- a/source/web/jsp/rules/details.jsp +++ b/source/web/jsp/rules/details.jsp @@ -125,5 +125,15 @@ + + + + + + + + + + \ No newline at end of file diff --git a/source/web/jsp/workflow/manage-task-dialog.jsp b/source/web/jsp/workflow/manage-task-dialog.jsp index 131268c079..f3816e9996 100644 --- a/source/web/jsp/workflow/manage-task-dialog.jsp +++ b/source/web/jsp/workflow/manage-task-dialog.jsp @@ -19,14 +19,14 @@ <%@ taglib uri="/WEB-INF/alfresco.tld" prefix="a" %> <%@ taglib uri="/WEB-INF/repo.tld" prefix="r" %> - - + @@ -38,60 +38,60 @@ initialSortColumn="name" initialSortDescending="true"> <%-- Name column --%> - + - + - - - + + <%-- Description column --%> - + - + - + <%-- Path column --%> - + - + - + <%-- Created Date column --%> - + - + - + <%-- Modified Date column --%> - + - + - + <%-- Actions column --%> - + - + - @@ -108,12 +108,14 @@ --%>
- - + + - - + + @@ -122,11 +124,11 @@
- + - + \ No newline at end of file diff --git a/source/web/jsp/workflow/reassign-task-dialog.jsp b/source/web/jsp/workflow/reassign-task-dialog.jsp index 0e14e13887..4a4f37b5c4 100644 --- a/source/web/jsp/workflow/reassign-task-dialog.jsp +++ b/source/web/jsp/workflow/reassign-task-dialog.jsp @@ -23,7 +23,7 @@ <%@ page buffer="32kb" contentType="text/html;charset=UTF-8" %> <%@ page isELIgnored="false" %> - + diff --git a/source/web/jsp/workflow/start-workflow-wizard/choose-workflow.jsp b/source/web/jsp/workflow/start-workflow-wizard/choose-workflow.jsp index a3799bbefb..1d90b698a0 100644 --- a/source/web/jsp/workflow/start-workflow-wizard/choose-workflow.jsp +++ b/source/web/jsp/workflow/start-workflow-wizard/choose-workflow.jsp @@ -19,10 +19,29 @@ <%@ taglib uri="/WEB-INF/alfresco.tld" prefix="a" %> <%@ taglib uri="/WEB-INF/repo.tld" prefix="r" %> - +<%@ page import="org.alfresco.web.ui.common.PanelGenerator" %> + + + + <%PanelGenerator.generatePanelStart(out, request.getContextPath(), "yellowInner", "#ffffcc");%> +
+ + + + + + + +
+ <%PanelGenerator.generatePanelEnd(out, request.getContextPath(), "yellowInner");%> +
+
+ + - \ No newline at end of file +
+ diff --git a/source/web/jsp/workflow/start-workflow-wizard/workflow-options.jsp b/source/web/jsp/workflow/start-workflow-wizard/workflow-options.jsp index 4e2b0af400..ca5e0873d8 100644 --- a/source/web/jsp/workflow/start-workflow-wizard/workflow-options.jsp +++ b/source/web/jsp/workflow/start-workflow-wizard/workflow-options.jsp @@ -21,7 +21,7 @@ <%@ page import="org.alfresco.web.ui.common.PanelGenerator" %> - + <%PanelGenerator.generatePanelStart(out, request.getContextPath(), "yellowInner", "#ffffcc");%>
@@ -37,97 +37,98 @@ - - + + + + + + + + + + - - + <%-- Name column --%> + + + + + + + + + + + <%-- Description column --%> + + + + + + + + <%-- Path column --%> + + + + + + + + <%-- Created Date column --%> + + + + + + + + + + <%-- Modified Date column --%> + + + + + + + + + + <%-- Actions column --%> + + + + + + + + + + + - - - - - - - <%-- Name column --%> - - - - - - - - - - - <%-- Description column --%> - - - - - - - - <%-- Path column --%> - - - - - - - - <%-- Created Date column --%> - - - - - - - - - - <%-- Modified Date column --%> - - - - - - - - - - <%-- Actions column --%> - - - - - - - - - - + + + + + - - - - - - - - - - - + + + diff --git a/source/web/jsp/workflow/tasks-completed-dashlet.jsp b/source/web/jsp/workflow/tasks-completed-dashlet.jsp index 0efb655524..8b624bc8cf 100644 --- a/source/web/jsp/workflow/tasks-completed-dashlet.jsp +++ b/source/web/jsp/workflow/tasks-completed-dashlet.jsp @@ -9,64 +9,64 @@ initialSortColumn="name" initialSortDescending="true"> <%-- Primary column for details view mode --%> - + - + - - <%-- Task id column --%> - + - + - + <%-- Source column --%> - + - + - + <%-- Completed date column --%> - + - + - + <%-- Outcome column --%> - + - + - + <%-- Actions column --%> - + - + - - + \ No newline at end of file diff --git a/source/web/jsp/workflow/tasks-todo-dashlet.jsp b/source/web/jsp/workflow/tasks-todo-dashlet.jsp index ee386f5ca5..3b1b872932 100644 --- a/source/web/jsp/workflow/tasks-todo-dashlet.jsp +++ b/source/web/jsp/workflow/tasks-todo-dashlet.jsp @@ -9,72 +9,72 @@ initialSortColumn="name" initialSortDescending="true"> <%-- Primary column for details view mode --%> - + - + - - <%-- Task id column --%> - + - + - + <%-- Source column --%> - + - + - + <%-- Due date column --%> - + - + - + <%-- Status column --%> - + - + - + <%-- Priority column --%> - + - + - + <%-- Actions column --%> - + - + - - + \ No newline at end of file diff --git a/source/web/jsp/workflow/view-completed-task-dialog.jsp b/source/web/jsp/workflow/view-completed-task-dialog.jsp index 6287762b9c..e93db93780 100644 --- a/source/web/jsp/workflow/view-completed-task-dialog.jsp +++ b/source/web/jsp/workflow/view-completed-task-dialog.jsp @@ -26,7 +26,7 @@ var="taskProps" columns="1" externalConfig="true" mode="view" /> - + @@ -38,61 +38,61 @@ initialSortColumn="name" initialSortDescending="true"> <%-- Name column --%> - + - + - - - + + <%-- Description column --%> - + - + - + <%-- Path column --%> - + - + - + <%-- Created Date column --%> - + - + - + <%-- Modified Date column --%> - + - + - + - + - +