From 7c7f733f644ecab1c8cdec7d0b16341948b33c7e Mon Sep 17 00:00:00 2001 From: Dave Ward Date: Wed, 9 Jun 2010 14:53:24 +0000 Subject: [PATCH] =?UTF-8?q?Merged=20V3.3=20to=20HEAD=20=20=20=2020440:=20R?= =?UTF-8?q?M:=20CapabilitiesTest.testDestroyRecordsCapability=20(MS=20SQL?= =?UTF-8?q?=20Server=20build)=20-=20use=20non-public=20nodeService=20=20?= =?UTF-8?q?=20=2020441:=20Include=20virtual=20tomcat=20in=20installers=20?= =?UTF-8?q?=20=20=2020442:=20Change=20bitrock=20builder=20version=20to=20u?= =?UTF-8?q?se.=20=20=20=2020443:=20Merged=20BRANCHES/DEV/V3.3-BUG-FIX=20to?= =?UTF-8?q?=20BRANCHES/V3.3:=20(Fixed=20tabs=20and=20removed=20'svn:execut?= =?UTF-8?q?able'=20and=20'svn:eol-style')=20=20=20=20=20=20=2020384:=20Mer?= =?UTF-8?q?ged=20BRANCHES/DEV/BELARUS/HEAD-2010=5F04=5F28=20to=20BRANCHES/?= =?UTF-8?q?DEV/V3.3-BUG-FIX:=20=20=20=20=20=20=20=20=20=2020271:=20ALF-803?= =?UTF-8?q?:=20Asset=20Service=20Improvements=20=20=20=20=20=20=2020386:?= =?UTF-8?q?=20Merged=20V2.2=20to=20V3.3-BUG-FIX=20=20=20=20=20=20=20=20=20?= =?UTF-8?q?=2020385:=20Merged=20DEV/BELARUS/V2.2-2010=5F04=5F06=20to=20V2.?= =?UTF-8?q?2=20=20=20=20=20=20=20=20=20=20=20=20=2020379:=20V2.2-ALF-1888?= =?UTF-8?q?=20AssociationQuery=20was=20corrected=20to=20filter=20...=20=20?= =?UTF-8?q?=20=20=20=20=2020387:=20Version=20Migrator=20(ALF-1000)=20-=20a?= =?UTF-8?q?pprox=20x3=20boost=20(policies=20ignore=20version2=20store)=20?= =?UTF-8?q?=20=20=20=20=20=2020388:=20Merged=20BRANCHES/DEV/BELARUS/HEAD-2?= =?UTF-8?q?010=5F04=5F28=20to=20BRANCHES/DEV/V3.3-BUG-FIX:=20=20=20=20=20?= =?UTF-8?q?=20=20=20=20=2020372:=20ALF-897:=20It=20is=20impossible=20to=20?= =?UTF-8?q?create=20content=20when=20default=20value=20selected=20in=20Con?= =?UTF-8?q?tentHeadlineBackground=20field=20for=20intranet=5Frssi=5Flandin?= =?UTF-8?q?g=5Ftemplate=20web-form=20(also=20fixes=20ALF-2798=20&=20ALF-79?= =?UTF-8?q?1)=20=20=20=20=20=20=2020389:=20Merged=20BRANCHES/DEV/BELARUS/H?= =?UTF-8?q?EAD-2010=5F04=5F28=20to=20BRANCHES/DEV/V3.3-BUG-FIX:=20=20=20?= =?UTF-8?q?=20=20=20=20=20=20=2020374:=20ALF-2723:=20WCM=20-=20Http=20500?= =?UTF-8?q?=20creating=20content=20via=20webform=20=20=20=20=20=20=2020394?= =?UTF-8?q?:=20Fix=20for=20ALF-2257=20-=20It's=20impossible=20to=20find=20?= =?UTF-8?q?and=20add=20group=20at=20Records=20Manage=20Permissions=20page?= =?UTF-8?q?=20=20=20=20=20=20=2020396:=20Fixed=20ALF-2956=20"XSS=20attack?= =?UTF-8?q?=20is=20made=20when=20a=20rule=20is=20being=20deleted"=20=20=20?= =?UTF-8?q?=20=20=20=2020397:=20Fix=20for=20ALF-922:=20Mysql=20does=20not?= =?UTF-8?q?=20support=20unique=20keys=20that=20contain=20nulls=20as=20one?= =?UTF-8?q?=20would=20expect=20=20=20=20=20=20=2020402:=20ALF-2186=20:=20R?= =?UTF-8?q?ules=20not=20being=20fired=20on=20datalist=20items=20-=20becaus?= =?UTF-8?q?e=20it's=20a=20zero=20byte=20file=3F=20=20=20=20=20=20=2020404:?= =?UTF-8?q?=20Fixed=20ALF-2109=20"Rule=20doesn't=20apply=20to=20the=20file?= =?UTF-8?q?s=20in=20sub-folders=20when=20'Run=20rule=20for=20this=20folder?= =?UTF-8?q?=20and=20its=20subfolders'=20action=20was=20performed"=20=20=20?= =?UTF-8?q?=20=20=20=2020406:=20Fix=20for=20ALF-2985=20-=20Share=20documen?= =?UTF-8?q?t=20library=20throws=20error=20if=20document=20modifier=20or=20?= =?UTF-8?q?creator=20is=20deleted=20from=20Alfresco=20=20=20=20=20=20=2020?= =?UTF-8?q?409:=20Improved=20FormServiceImplTest,=20added=20more=20content?= =?UTF-8?q?=20related=20tests=20and=20some=20edge=20case=20tests=20using?= =?UTF-8?q?=20the=20FDK=20model=20(this=20test=20needs=20to=20be=20manuall?= =?UTF-8?q?y=20enabled=20though=20as=20the=20FDK=20model=20is=20not=20avai?= =?UTF-8?q?lable=20by=20default)=20=20=20=20=20=20=2020414:=20Merged=20DEV?= =?UTF-8?q?/BELARUS/HEAD-2010=5F04=5F28=20to=20DEV/V3.3-BUG-FIX=20=20=20?= =?UTF-8?q?=20=20=20=20=20=20=2020401:=20ALF-2616:=20Serious=20Web=20Form?= =?UTF-8?q?=20layout=20performance=20issues=20on=20IE8.=20This=20fix=20con?= =?UTF-8?q?tains:=20=20=20=20=20=20=2020427:=20Merged=20DEV/BELARUS/HEAD-2?= =?UTF-8?q?010=5F04=5F28=20to=20DEV/V3.3-BUG-FIX=20=20=20=20=20=20=20=20?= =?UTF-8?q?=20=2020042:=20ALF-1523:=20Failed=20Kerberos=20SSO=20auth=20doe?= =?UTF-8?q?sn't=20fail=20through,=20simply=20returns=20a=20blank=20page=20?= =?UTF-8?q?=20=20=20=20=20=20=20=20=2020323:=20ALF-1523:=20Failed=20Kerber?= =?UTF-8?q?os=20SSO=20auth=20doesn't=20fail=20through,=20simply=20returns?= =?UTF-8?q?=20a=20blank=20page=20=20=20=20=20=20=2020428:=20Merged=20DEV/B?= =?UTF-8?q?ELARUS/HEAD-2010=5F04=5F28=20to=20DEV/V3.3-BUG-FIX=20=20=20=20?= =?UTF-8?q?=20=20=20=20=20=2020417:=20ALF-736:=20WebDAV=20Folder=20Renamin?= =?UTF-8?q?g=20fails=20on=20Mac=20but=20works=20on=20Windows.=20=20=20=20?= =?UTF-8?q?=20=20=2020430:=20Fix=20for=20ALF-2313=20-=20Accessing=20a=20Do?= =?UTF-8?q?clib=20folder=20in=20Share=20which=20has=20a=20link=20to=20a=20?= =?UTF-8?q?deleted=20node=20fails=20=20=20=20=20=20=2020431:=20Version=20M?= =?UTF-8?q?igrator=20(ALF-1000)=20-=20migrate=201st=20batch=20independentl?= =?UTF-8?q?y=20=20=20=20=20=20=2020432:=20Fix=20for=20ALF-2327=20-=20Can?= =?UTF-8?q?=20not=20have=20more=20than=20one=20Transfer=20Step=20in=20a=20?= =?UTF-8?q?disposal=20schedule=20=20=20=20=20=20=2020438:=20ALF-479:=20Mer?= =?UTF-8?q?ged=20DEV/BELARUS/V3.2-2010=5F01=5F11=20to=20DEV/V3.3-BUG-FIX?= =?UTF-8?q?=20=20=20=20=20=20=20=20=20=2018448:=20ETHREEOH-4044:=20Externa?= =?UTF-8?q?l=20Authentication=20Subsystem=20does=20not=20perform=20user=20?= =?UTF-8?q?mapping=20for=20WebDAV=20requests=20=20=20=2020444:=20Fix=20for?= =?UTF-8?q?=20ConcurrentModificationException=20in=20file=20server=20quota?= =?UTF-8?q?=20manager.=20ALF-2970.=20=20=20=2020445:=20Merged=20HEAD=20to?= =?UTF-8?q?=20BRANCHES/V3.3:=20(RECORD=20ONLY)=20=20=20=20=20=20=2020413:?= =?UTF-8?q?=20Added=20clean=20of=20quickr=20project=20=20=20=2020446:=20Ch?= =?UTF-8?q?anged=20version=20to=203.3.1dev=20=20=20=2020447:=20Merged=20V3?= =?UTF-8?q?.3-BUG-FIX=20to=20V3.3=20=20=20=20=20=20=2020294:=20Fixes:=20AL?= =?UTF-8?q?F-1020=20&=20ALF-1013=20for=20all=20views=20except=20agenda.=20?= =?UTF-8?q?=20=20=2020451:=20Merged=20V2.2=20to=20V3.3=20=20=20=20=20=20?= =?UTF-8?q?=2020450:=20Merged=20DEV/BELARUS/V2.2-2010=5F04=5F06=20to=20V2.?= =?UTF-8?q?2=20=20=20=20=20=20=20=20=20=2020412:=20ALF-1887:=20too=20easy?= =?UTF-8?q?=20to=20break=20alfresco=20-=20one=20can=20remove=20the=20guest?= =?UTF-8?q?=20user=20and=20recreate=20it=20but=20then=20access=20to=20RSS?= =?UTF-8?q?=20is=20broken=20=20=20=20=20=20=20=20=20=20=20=20=20-=20Person?= =?UTF-8?q?ServiceImpl.beforeDeleteNode=20prohibits=20attempts=20to=20dele?= =?UTF-8?q?te=20a=20guest=20user.=20=20=20=2020452:=20Fix=20for=20transact?= =?UTF-8?q?ion=20error=20from=20NFS=20server=20file=20expiry=20thread.=20A?= =?UTF-8?q?LF-3016.=20=20=20=2020458:=20ALF-2729=20-=20rationalise=20(and?= =?UTF-8?q?=20deprecate)=20VersionLabelComparator=20=20=20=2020460:=20Fix?= =?UTF-8?q?=20for=20ALF-2430=20=20=20=20=20=20=20-=20AVM=20nodes=20are=20n?= =?UTF-8?q?ot=20checked=20for=20exclusion=20-=20the=20default=20ACLEntryVo?= =?UTF-8?q?ter=20will=20always=20vote=20for=20AVM=20=20=20=20=20=20=20-=20?= =?UTF-8?q?avoids=20embedded=20AVM=20permission=20checks=20for=20getType/g?= =?UTF-8?q?etAspect=20and=20anything=20else=20that=20may=20be=20added=20?= =?UTF-8?q?=20=20=20=20=20=20-=20seems=20AVM=20read=20is=20not=20checked?= =?UTF-8?q?=20upon=20"lookup"=20for=20the=20last=20node=20in=20the=20PATH?= =?UTF-8?q?=20(getType=20should=20have=20failed=20too)=20=20=20=2020466:?= =?UTF-8?q?=20Merged=20V2.2=20to=20V3.3=20=20=20=20=20=20=2020243:=20(RECO?= =?UTF-8?q?RD=20ONLY)=20ALF-2814:=20Merged=20V3.2=20to=20V2.2=20=20=20=20?= =?UTF-8?q?=20=20=20=20=20=2017891:=20Merged=20DEV=5FTEMPORARY=20to=20V3.2?= =?UTF-8?q?=20=20=20=20=20=20=20=20=20=20=20=20=2017873:=20ETHREEOH-3810:?= =?UTF-8?q?=20WCM=20-=20Recursion=20detector=20erroring=20=20=20=2020467:?= =?UTF-8?q?=20Merged=20V3.1=20to=20V3.3=20(RECORD=20ONLY)=20=20=20=20=20?= =?UTF-8?q?=20=2020276:=20Incremented=20version=20label=20=20=20=20=20=20?= =?UTF-8?q?=2020275:=20ALF-2845:=20Merged=20V3.2=20to=20V3.1=20=20=20=20?= =?UTF-8?q?=20=20=20=20=20=2017768:=20Merged=20DEV/BELARUS/V3.2-2009=5F11?= =?UTF-8?q?=5F24=20to=20V3.2=20=20=20=20=20=20=20=20=20=20=20=20=2017758:?= =?UTF-8?q?=20ETHREEOH-3757:=20Oracle=20upgrade=20issue:=20failed=20"invit?= =?UTF-8?q?eEmailTemplate"=20patch=20-=20also=20causes=20subsequent=20patc?= =?UTF-8?q?hes=20to=20not=20be=20applied=20=20=20=20=20=20=2019573:=20Merg?= =?UTF-8?q?ed=20V3.2=20to=20V3.1=20=20=20=20=20=20=20=20=20=2019539:=20Mer?= =?UTF-8?q?ged=20HEAD=20to=20V3.2=20=20=20=20=20=20=20=20=20=20=20=20=2019?= =?UTF-8?q?538:=20Build=20fix=20-=20fix=20build=20speed=20=20=20=2020468:?= =?UTF-8?q?=20Merged=20PATCHES/V3.2.r=20to=20V3.3=20(RECORD=20ONLY)=20=20?= =?UTF-8?q?=20=20=20=20=2020357:=20Merged=20PATCHES/V3.2.0=20to=20PATCHES/?= =?UTF-8?q?V3.2.r=20=20=20=20=20=20=20=20=20=2020349:=20Merged=20V3.3=20to?= =?UTF-8?q?=20PATCHES/V3.2.0=20=20=20=20=20=20=20=20=20=20=20=20=2020346:?= =?UTF-8?q?=20ALF-2839:=20Node=20pre-loading=20generates=20needless=20resu?= =?UTF-8?q?ltset=20rows=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20-?= =?UTF-8?q?=20Added=20missing=20Criteria.list()=20call=20=20=20=20=20=20?= =?UTF-8?q?=2020339:=20Incremented=20version=20label=20=20=20=20=20=20=202?= =?UTF-8?q?0338:=20Merged=20PATCHES/V3.2.0=20to=20PATCHES/V3.2.r=20=20=20?= =?UTF-8?q?=20=20=20=20=20=20=2020280:=20Fixed=20ALF-2839:=20Node=20pre-lo?= =?UTF-8?q?ading=20generates=20needless=20resultset=20rows=20=20=20=20=20?= =?UTF-8?q?=20=20=20=20=20=20=20=20-=20Split=20Criteria=20query=20to=20ret?= =?UTF-8?q?rieve=20properties=20and=20aspects=20separately=20=20=20=20=20?= =?UTF-8?q?=20=20=20=20=2020272:=20Backports=20to=20help=20fix=20ALF-2839:?= =?UTF-8?q?=20Node=20pre-loading=20generates=20needless=20resultset=20rows?= =?UTF-8?q?=20=20=20=20=20=20=20=20=20=20=20=20=20Merged=20BRANCHES/V3.2?= =?UTF-8?q?=20to=20PATCHES/V3.2.0:=20=20=20=20=20=20=20=20=20=20=20=20=20?= =?UTF-8?q?=20=20=2018490:=20Added=20cache=20for=20alf=5Fcontent=5Fdata=20?= =?UTF-8?q?=20=20=20=20=20=20=20=20=20=20=20=20Merged=20BRANCHES/DEV/V3.3-?= =?UTF-8?q?BUG-FIX=20to=20PATCHES/V3.2.0:=20=20=20=20=20=20=20=20=20=20=20?= =?UTF-8?q?=20=20=20=20=2020231:=20Fixed=20ALF-2784:=20Degradation=20of=20?= =?UTF-8?q?performance=20between=203.1.1=20and=203.2x=20(observed=20in=20J?= =?UTF-8?q?SF)=20=20=20=20=20=20=20=20=20=2020266:=20Test=20reproduction?= =?UTF-8?q?=20of=20ALF-2839=20failure:=20Node=20pre-loading=20generates=20?= =?UTF-8?q?needless=20resultset=20rows=20=20=20=2020469:=20Merged=20PATCHE?= =?UTF-8?q?S/V3.1.2=20to=20V3.3=20(RECORD=20ONLY)=20=20=20=20=20=20=202039?= =?UTF-8?q?3:=20Eclipse=20classpath=20fix=20to=20avoid=20problems=20in=20J?= =?UTF-8?q?Boss=20=20=20=20=20=20=2020309:=20ALF-2777:=20PrimaryChildAssoc?= =?UTF-8?q?CopyBehaviour=20from=20MOB-388=20corrupts=20cm:name=20attribute?= =?UTF-8?q?s=20of=20copied=20child=20nodes=20=20=20=20=20=20=20=20=20=20-?= =?UTF-8?q?=20Folded=20example=20behaviours=20from=20previous=20AMP=20into?= =?UTF-8?q?=20repository=20=20=20=20=20=20=20=20=20=20-=20Fixed=20PrimaryC?= =?UTF-8?q?hildAssocCopyBehaviour=20to=20back-up=20and=20set=20the=20cm:na?= =?UTF-8?q?me=20property=20on=20copied=20children=20=20=20=2020470:=20Merg?= =?UTF-8?q?ed=20PATCHES/V3.2.0=20to=20V3.3=20(RECORD=20ONLY)=20=20=20=20?= =?UTF-8?q?=20=20=2020465:=20Incremented=20version=20label=20=20=20=20=20?= =?UTF-8?q?=20=2020464:=20ALF-3060:=20Merged=20V3.2=20to=20PATCHES/V3.2.0?= =?UTF-8?q?=20=20=20=20=20=20=20=20=20=2019920:=20Merged=20HEAD=20to=20BRA?= =?UTF-8?q?NCHES/V3.2:=20=20=20=20=20=20=20=20=20=20=20=20=2019918:=20Fix?= =?UTF-8?q?=20ALF-2499=20(Deleting=20a=20web=20project=20also=20deletes=20?= =?UTF-8?q?similarly=20named=20web=20projects=20-=20Potential=20Data=20Los?= =?UTF-8?q?s)=20=20=20=20=20=20=2020448:=20Merged=20DEV/V3.3-BUG-FIX=20to?= =?UTF-8?q?=20PATCHES/V3.2.0=20=20=20=20=20=20=20=20=20=2020414:=20Merged?= =?UTF-8?q?=20DEV/BELARUS/HEAD-2010=5F04=5F28=20to=20DEV/V3.3-BUG-FIX=20?= =?UTF-8?q?=20=20=20=20=20=20=20=20=20=20=20=2020401:=20ALF-2616:=20Seriou?= =?UTF-8?q?s=20Web=20Form=20layout=20performance=20issues=20on=20IE8.=20Th?= =?UTF-8?q?is=20fix=20contains:=20=20=20=20=20=20=20=20=20=20=20=20=20=20?= =?UTF-8?q?=20=20a)=20X-UA-Compatible=20head=20tag=20with=20IE=3DEmulateIE?= =?UTF-8?q?7=20value=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20b)=20a?= =?UTF-8?q?lfresco.ieVersion=20and=20alfresco.ieEngine=20in=20common.js=20?= =?UTF-8?q?=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20c)=20recurseOnChil?= =?UTF-8?q?dren=20in=20=5FupdateDisplay=20=20=20=20=20=20=20=20=20=20=20?= =?UTF-8?q?=20=20=20=20=20d)=20Some=20performance=20modifications=20in=20x?= =?UTF-8?q?forms.js=20=20=20=20=20=20=2020350:=20Increment=20version=20lab?= =?UTF-8?q?el=20=20=20=20=20=20=2020349:=20Merged=20V3.3=20to=20PATCHES/V3?= =?UTF-8?q?.2.0=20=20=20=20=20=20=20=20=20=2020346:=20ALF-2839:=20Node=20p?= =?UTF-8?q?re-loading=20generates=20needless=20resultset=20rows=20=20=20?= =?UTF-8?q?=20=20=20=20=20=20=20=20=20=20-=20Added=20missing=20Criteria.li?= =?UTF-8?q?st()=20call=20=20=20=2020471:=20Fix=20for=20offline=20sync=20lo?= =?UTF-8?q?sing=20metadata=20properties,=20due=20to=20rename/delete=20of?= =?UTF-8?q?=20original=20file.=20ALF-575.=20=20=20=2020478:=20Merged=20HEA?= =?UTF-8?q?D=20to=20BRANCHES/V3.3:=20(RECORD=20ONLY)=20=20=20=20=20=20=202?= =?UTF-8?q?0477:=20Fix=20ALF-3086:=20CMIS=20checkin=20of=20a=20non-version?= =?UTF-8?q?able=20document=20should=20make=20it=20versionable=20=20=20=202?= =?UTF-8?q?0479:=20ALF-2110:=20Make=20it=20possible=20to=20determine=20whi?= =?UTF-8?q?ch=20person=20properties=20are=20synced=20via=20LDAP=20and=20he?= =?UTF-8?q?nce=20immutable=20=20=20=20=20=20=20-=20Added=20Set=20Us?= =?UTF-8?q?erRegistrySynchronizer.getPersonMappedProperties(String=20usern?= =?UTF-8?q?ame)=20=20=20=20=20=20=20-=20UI/Services=20Fix=20to=20follow=20?= =?UTF-8?q?=20=20=2020481:=20Latest=20SpringSurf=20libs:=20=20=20=20=20=20?= =?UTF-8?q?=20-=20Fix=20for=20ALF-1518=20-=20Added=20support=20for=20HTTP?= =?UTF-8?q?=20and=20HTTPS=20proxies=20for=20Surf=20application=20remote=20?= =?UTF-8?q?api=20calls=20-=20via=20the=20standard=20JVM=20cmd=20line=20pro?= =?UTF-8?q?perties=20such=20as=20-Dhttp.proxyHost=3D...=20=20=20=2020484:?= =?UTF-8?q?=20ALF-2886:=20LDAP=20sync=20defaults=20display=20names=20incor?= =?UTF-8?q?rectly=20and=20can't=20cope=20with=20DNs=20containing=20escaped?= =?UTF-8?q?=20trailing=20whitespace.=20=20=20=20=20=20=20-=20Had=20to=20wo?= =?UTF-8?q?rk=20around=20a=20JDK=20bug=20in=20LDAP=20RDN=20parsing=20=20?= =?UTF-8?q?=20=2020486:=20Added=20case=20sensitive=20flag=20to=20the=20fil?= =?UTF-8?q?e=20state=20cache.=20Part=20of=20ALF-570.=20=20=20=2020487:=20F?= =?UTF-8?q?ix=20for=20copy/rename=20of=20folders=20causing=20file=20exists?= =?UTF-8?q?=20errors=20in=20some=20cases.=20ALF-570.=20=20=20=2020488:=20F?= =?UTF-8?q?ix=20ALF-680:=20Previously=20valid=20content=20models=20now=20f?= =?UTF-8?q?ail=20with=20CMISAbstractDictionaryService$DictionaryRegistry?= =?UTF-8?q?=20exception=20=20=20=2020489:=20Uploaded=20correct=20version?= =?UTF-8?q?=20of=20spring=20source=20jars=20and=20reunited=20them=20with?= =?UTF-8?q?=203rd-party/.classpath=20=20=20=2020490:=20Fix=20for=20cannot?= =?UTF-8?q?=20delete=20folders=20via=20CIFS=20from=20Mac=20OSX,=20due=20to?= =?UTF-8?q?=20desktop=20actions.=20ALF-2553.=20=20=20=2020491:=20Merged=20?= =?UTF-8?q?DEV/TEMPORARY=20to=20V3.3=20(With=20corrections)=20=20=20=20=20?= =?UTF-8?q?=20=2020485:=20ALF-2290:=20a=20HTTP=20GET=20request=20of=20a=20?= =?UTF-8?q?document=20redirects=20to=20the=20Home=20Location=20when=20usin?= =?UTF-8?q?g=20NTLM=20SSO=20=20=20=20=20=20=20=20=20=20The=20logic=20relat?= =?UTF-8?q?ed=20to=20ADB-61=20in=20NTLMAuthenticationFilter=20clears=20pre?= =?UTF-8?q?vious=20location=20and=20redirects=20request=20to=20default=20h?= =?UTF-8?q?ome=20location.=20NTLMAuthenticationFilter=20was=20changed=20to?= =?UTF-8?q?=20process=20GET=20requests=20to=20documents=20correctly.=20Now?= =?UTF-8?q?,=20fix=20to=20ADB-61=20processes=20only=20=E2=80=9C/faces?= =?UTF-8?q?=E2=80=9D=20requests=20and=20GET=20requests=20to=20documents=20?= =?UTF-8?q?are=20processed=20correctly.=20=20=20=20=20=20=20=20=20=20The?= =?UTF-8?q?=20same=20fix=20was=20made=20to=20KerberosAuthenticationFilter?= =?UTF-8?q?=20=20=20=2020492:=20Fix=20ALF-680:=20Previously=20valid=20cont?= =?UTF-8?q?ent=20models=20now=20fail=20with=20CMISAbstractDictionaryServic?= =?UTF-8?q?e$DictionaryRegistry=20exception=20=20=20=20=20=20=20-=20missin?= =?UTF-8?q?g=20remove=20directory=20=20=20=2020493:=20Fix=20ALF-2837:=20Cl?= =?UTF-8?q?assCastException=20in=20getProperties()=20=20=20=2020498:=20Fix?= =?UTF-8?q?=20for=20ALF-2818:=20Failure=20to=20close=20index=20writer=20un?= =?UTF-8?q?der=20certain=20conditions.=20=20=20=20=20=20=20-=20fix=20for?= =?UTF-8?q?=20index=20writer=20to=20close=20indexes=20when=20stopped=20by?= =?UTF-8?q?=20exceptions=20during=20FTS=20=20=20=20=20=20=20-=20fix=20FTS?= =?UTF-8?q?=20job=20to=20handle=20exceptions=20better=20=20=20=20=20=20=20?= =?UTF-8?q?-=20debug=20for=20FTS=20background=20operations=20=20=20=202049?= =?UTF-8?q?9:=20ALF-3094:=20In=20ticket=20authenticate=20method=20in=20Aut?= =?UTF-8?q?henticationHelper,=20invalidate=20the=20current=20session=20if?= =?UTF-8?q?=20its=20cached=20ticket=20doesn't=20match=20=20=20=2020500:=20?= =?UTF-8?q?Fix=20for=20ALF-2858=20"Zero=20KB=20sized=20bin=20files=20will?= =?UTF-8?q?=20be=20created=20in=20the=20contentstore=20when=20new=20sites?= =?UTF-8?q?=20are=20created"=20(RECORD=20ONLY)=20=20=20=2020503:=20AVMTest?= =?UTF-8?q?Suite:=20minor=20fixes=20to=20cleanup=20ctx=20usage=20(avoid=20?= =?UTF-8?q?re-loading)=20=20=20=2020505:=20Merged=20BRANCHES/V2.2=20to=20B?= =?UTF-8?q?RANCHES/V3.3=20(record-only)=20=20=20=20=20=20=2013859:=20(reco?= =?UTF-8?q?rd-only)=20Removed=20dev=20from=20version=20label=20=20=20=20?= =?UTF-8?q?=20=20=2014003:=20(record-only)=20Updated=20version=20to=202.2.?= =?UTF-8?q?5dev=20=20=20=20=20=20=2014566:=20(record-only)=20ETWOTWO-1239?= =?UTF-8?q?=20-=20remove=20workflow=20interpreter/console=20bootstrap=20?= =?UTF-8?q?=20=20=20=20=20=2014572:=20(record-only)=20ETWOTWO-1239=20-=20f?= =?UTF-8?q?ix=20PersonTest=20to=20fix=20JBPMEngineTest=20(part-sourced=20f?= =?UTF-8?q?rom=20r13247)=20=20=20=20=20=20=2014776:=20(record-only)=20Merg?= =?UTF-8?q?ed=20V3.1=20to=20V2.2=20=20=20=20=20=20=20=20=20=2014748:=20ETH?= =?UTF-8?q?REEOH-2225=20-=20WCM=20upgrade=20(performance=20improvements=20?= =?UTF-8?q?for=20MySQL)=20=20=20=2020506:=20NFS=20ReadDir/ReadDirPlus=20sk?= =?UTF-8?q?ips=20some=20folder=20entries.=20JLAN-98.=20=20=20=2020507:=20F?= =?UTF-8?q?ixed=20issue=20with=20folder=20search=20resume=20id=20being=20r?= =?UTF-8?q?eset=20to=20the=20wrong=20value=20during=20NFS=20folder=20searc?= =?UTF-8?q?h.=20Part=20of=20JLAN-98.=20=20=20=2020508:=20Merged=20BRANCHES?= =?UTF-8?q?/V3.2=20to=20BRANCHES/V3.3:=20=20=20=20=20=20=2018319:=20Merged?= =?UTF-8?q?=20BRANCHES/DEV/BELARUS/V3.2-2010=5F01=5F11=20to=20V3.2=20=20?= =?UTF-8?q?=20=20=20=20=20=20=20=2018273:=20ETHREEOH-3834:=20WCM:=20An=20e?= =?UTF-8?q?xtral=20.xml.html=20file=20is=20created=20when=20editing=20newl?= =?UTF-8?q?y=20created=20content=20=20=20=20=20=20=2019182:=20Merged=20V3.?= =?UTF-8?q?1=20to=20V3.2=20=20=20=20=20=20=20=20=20=2018423:=20ETHREEOH-38?= =?UTF-8?q?50=20-=20Content=20Manager=20unable=20to=20edit=20content=20ite?= =?UTF-8?q?ms=20if=20there=20is=20a=20lock=20on=20a=20generated=20renditio?= =?UTF-8?q?n=20=20=20=20=20=20=20=20=20=2018432:=20(RECORD=20ONLY)=20Added?= =?UTF-8?q?=20FTP=20data=20port=20range=20configuration=20via=20n:n=20config=20value.=20ETHREEOH-4103.=20=20=20=20?= =?UTF-8?q?=20=20=20=20=20=2018451:=20(RECORD=20ONLY)=20Fixed=20incorrect?= =?UTF-8?q?=20FTP=20debug=20level=20name.=20=20=20=20=20=20=20=20=20=20185?= =?UTF-8?q?77:=20(RECORD=20ONLY)=20Fix=20for=20ETHREEOH-4117,=20based=20on?= =?UTF-8?q?=20CHK-11154=20=20=20=20=20=20=20=20=20=2018792:=20Fix=20ETHREE?= =?UTF-8?q?OH-2729:=20=20Import=20of=20property=20with=20@=20symbol=20in?= =?UTF-8?q?=20name=20fails=20with=20"start=20tag=20unexpected=20character?= =?UTF-8?q?=20@=20"=20=20=20=20=20=20=2019570:=20ALF-192=20/=20ALF-1750:?= =?UTF-8?q?=20=20System=20Error=20if=20user=20trying=20submit=20web=20cont?= =?UTF-8?q?ent=20based=20on=20web=20form=20which=20was=20deleted=20=20=20?= =?UTF-8?q?=20=20=20=2019583:=20Merged=20DEV/BELARUS/V3.2-2010=5F03=5F17?= =?UTF-8?q?=20to=20V3.2=20=20=20=20=20=20=20=20=20=2019545:=20ALF-1954:=20?= =?UTF-8?q?Regression:=20same=20item=20can=20be=20submitted=20multiple=20t?= =?UTF-8?q?imes=20to=20workflow=20=20=20=20=20=20=2019725:=20AVMStoreDescr?= =?UTF-8?q?iptor=20-=20fix=20minor=20typo=20(for=20debugging)=20=20=20=20?= =?UTF-8?q?=20=20=2019917:=20(RECORD=20ONLY)=20Merged=20HEAD=20to=20BRANCH?= =?UTF-8?q?ES/V3.2:=20=20=20=20=20=20=20=20=20=2019880:=20Fix=20ALF-898=20?= =?UTF-8?q?-=20WCM:=20Deleting=20a=20file=20leads=20to=20error=20(only=20i?= =?UTF-8?q?f=20RM/DOD=20installed)=20=20=20=20=20=20=2019920:=20(RECORD=20?= =?UTF-8?q?ONLY)=20Merged=20HEAD=20to=20BRANCHES/V3.2:=20=20=20=20=20=20?= =?UTF-8?q?=20=20=20=2019918:=20Fix=20ALF-2499=20(Deleting=20a=20web=20pro?= =?UTF-8?q?ject=20also=20deletes=20similarly=20named=20web=20projects=20-?= =?UTF-8?q?=20Potential=20Data=20Loss)=20=20=20=2020509:=20Merged=20BRANCH?= =?UTF-8?q?ES/V3.2=20to=20BRANCHES/V3.3=20(RECORD=20ONLY):=20=20=20=20=20?= =?UTF-8?q?=20=2019825:=20(RECORD=20ONLY)=20Merged=20PATCHES/V3.2.r=20to?= =?UTF-8?q?=20BRANCHES/V3.2:=20=20=20=20=20=20=20=20=20=2019804:=20Merged?= =?UTF-8?q?=20PATCHES/V3.2.0=20to=20PATCHES/V3.2.r=20=20=20=20=20=20=20=20?= =?UTF-8?q?=20=20=20=20=20Merged=20HEAD=20to=20V3.2.0=20=20=20=20=20=20=20?= =?UTF-8?q?=20=20=20=20=20=20...=20=20=20=2020510:=20Merged=20BRANCHES/V3.?= =?UTF-8?q?1=20to=20BRANCHES/V3.3=20(RECORD=20ONLY)=20=20=20=20=20=20=2017?= =?UTF-8?q?482:=20(RECORD=20ONLY)=20Merged=20V3.2=20to=20V3.1=20=20=20=20?= =?UTF-8?q?=20=20=20=20=20=2017478:=20Fix=20ETHREEOH-3340=20-=20WCM=20-=20?= =?UTF-8?q?Revert=20to=20snapshot=20failure=20(fix=20AVM=20getListing=20->?= =?UTF-8?q?=20AVMSync=20compare=20->=20WCM=20revertSnapshot)=20=20=20=20?= =?UTF-8?q?=20=20=2018783:=20(RECORD=20ONLY)=20MT:=20ensure=20group=20(EMA?= =?UTF-8?q?IL=5FCONTRIBUTORS)=20bootstraps=20tenant=20admin=20user=20(when?= =?UTF-8?q?=20creating=20tenant)=20=20=20=2020513:=20Added=20port=20change?= =?UTF-8?q?=20example=20for=20remote=20Alfresco=20server=20to=20share-conf?= =?UTF-8?q?ig-custom.xml.sample=20=20=20=2020518:=20ALF-657=20Created=20te?= =?UTF-8?q?sts=20to=20check=20that=20the=20'runas'=20functionality=20works?= =?UTF-8?q?=20in=20the=20AlfrescoJavaScript=20action=20handler.=20Also=20m?= =?UTF-8?q?odified=20the=20handler=20to=20run=20as=20the=20System=20user?= =?UTF-8?q?=20if=20no=20Authentication=20is=20currently=20set,=20as=20may?= =?UTF-8?q?=20occur=20if=20the=20action=20handler=20is=20being=20executed?= =?UTF-8?q?=20asynchronously.=20=20=20=2020519:=20ALF-657=20Created=20test?= =?UTF-8?q?s=20to=20check=20that=20the=20'runas'=20functionality=20works?= =?UTF-8?q?=20in=20the=20AlfrescoJavaScript=20action=20handler.=20Also=20m?= =?UTF-8?q?odified=20the=20handler=20to=20run=20as=20the=20System=20user?= =?UTF-8?q?=20if=20no=20Authentication=20is=20currently=20set,=20as=20may?= =?UTF-8?q?=20occur=20if=20the=20action=20handler=20is=20being=20executed?= =?UTF-8?q?=20asynchronously.=20=20=20=2020520:=20Removed=20dev=20version.?= =?UTF-8?q?label=20=20=20=2020522:=20ALF-3129:=20Map=20cm:organization=20p?= =?UTF-8?q?roperty=20in=20LDAP=20as=20well=20as=20cm:organizationId,=20sin?= =?UTF-8?q?ce=20cm:organization=20is=20what=20shows=20up=20in=20JSF=20and?= =?UTF-8?q?=20Share.=20Needed=20by=20ALF-2110.=20=20=20=2020523:=20First?= =?UTF-8?q?=20part=20of=20fix=20for=20ALF-2110:=20=20=20=20=20=20=20-=20Ap?= =?UTF-8?q?propriate=20Person=20and=20webframework=20metadata=20APIs=20now?= =?UTF-8?q?=20return=20information=20on=20immutability=20of=20Person=20pro?= =?UTF-8?q?perties=20(as=20some=20properties=20are=20immutable=20when=20sy?= =?UTF-8?q?nced=20to=20LDAP=20etc.)=20=20=20=20=20=20=20-=20Share=20client?= =?UTF-8?q?=20=20now=20correctly=20disables=20profile=20fields=20in=20User?= =?UTF-8?q?=20Profile=20and=20Admin=20User=20Console=20as=20appropriate=20?= =?UTF-8?q?based=20on=20individual=20user=20property=20mutability=20=20=20?= =?UTF-8?q?=20=20=20=20-=20Change=20Password=20button=20now=20correctly=20?= =?UTF-8?q?enabled/disabled=20based=20on=20account=20mutability=20=20=20?= =?UTF-8?q?=2020524:=20VersionMigrator=20-=20option=20to=20run=20as=20sche?= =?UTF-8?q?duled=20job=20(ALF-1000)=20=20=20=2020525:=20Fix=20for=20variou?= =?UTF-8?q?s=20IE6=20CSS=20issues:=20=20=20=20=20=20=20ALF-3047=20-=20It's?= =?UTF-8?q?=20impossible=20to=20destinate=20any=20action=20with=20data=20l?= =?UTF-8?q?ist=20item=20(IE6=20specific)=20=20=20=20=20=20=20ALF-3049=20-?= =?UTF-8?q?=20Incorrect=20layout=20of=20Manage=20aspects=20page=20=20=20?= =?UTF-8?q?=20=20=20=20ALF-3050=20-=20Incorrect=20layout=20of=20Assign=20W?= =?UTF-8?q?orkflow=20form=20=20=20=2020526:=20Fix=20for=20ALF-2915=20-=20S?= =?UTF-8?q?elect=20>=20None=20feature=20for=20Data=20Lists=20not=20working?= =?UTF-8?q?=20across=20multiple=20pages=20in=20IE=20=20=20=20=20=20=20Clos?= =?UTF-8?q?ed=20ALF-2846=20-=20DataList=20UI=20not=20fully=20I18Ned=20[Old?= =?UTF-8?q?=20prototype=20code]=20=20=20=2020527:=20Fix=20for=20ALF-3082?= =?UTF-8?q?=20-=20There=20is=20no=20Edit=20Offline=20action=20at=20Details?= =?UTF-8?q?=20page=20in=20Share=20site=20=20=20=2020528:=20Fix=20various?= =?UTF-8?q?=20script=20errors=20due=20to=20typo:=20=20=20=20=20=20=20ALF-3?= =?UTF-8?q?088=20-=20Script=20error=20occurs=20on=20creating=20duplicated?= =?UTF-8?q?=20record=20seria=20=20=20=20=20=20=20ALF-3012=20-=20Incorrect?= =?UTF-8?q?=20behaviour=20on=20creating=20duplicating=20folders=20=20=20?= =?UTF-8?q?=20=20=20=20ALF-3004=20-=20Script=20error=20when=20submitting?= =?UTF-8?q?=20an=20item=20with=20long=20data=20in=20Prioprity=20field=20?= =?UTF-8?q?=20=20=2020529:=20Fix=20for=20ALF-3006=20-=20Selected=20Items?= =?UTF-8?q?=20>=20Copy=20to...=20and=20Move=20to=20actions=20not=20working?= =?UTF-8?q?=20in=20Document=20Library=20=20=20=2020530:=20Dynamic=20Models?= =?UTF-8?q?=20-=20fix=20test(s)=20=20=20=20=20=20=20-=20fix=20concurrency?= =?UTF-8?q?=20test=20for=20Oracle=20build=20(retry=20if=20txn=20lock=20can?= =?UTF-8?q?not=20be=20acquired)=20=20=20=20=20=20=20-=20when=20getting=20d?= =?UTF-8?q?eployed=20models,=20skip=20if=20invalid=20(eg.=20cannot=20be=20?= =?UTF-8?q?parsed)=20=20=20=2020536:=20Remove=20@Override=20(ALF-657)=20?= =?UTF-8?q?=20=20=2020537:=20Activities=20-=20(minor)=20fix=20NPE=20for=20?= =?UTF-8?q?Oracle=20build/test=20=20=20=2020543:=20Final=20part=20of=20ALF?= =?UTF-8?q?-2110=20-=20Appropriate=20person=20properties=20disabled=20for?= =?UTF-8?q?=20editing=20in=20Explorer=20Client=20if=20external=20mapped=20?= =?UTF-8?q?sync=20such=20as=20LDAP=20is=20used.=20=20=20=20=20=20=20Fixed?= =?UTF-8?q?=20issue=20with=20Change=20Password=20option=20being=20disabled?= =?UTF-8?q?=20incorrectly.=20=20=20=2020544:=20Follow-up=20fix=20to=20r205?= =?UTF-8?q?28=20=20=20=2020546:=20Fix=20for=20ALF-3151=20-=20Freemarker=20?= =?UTF-8?q?causes=20NPE=20while=20deploying=203.3=20enterprise=20onto=20We?= =?UTF-8?q?bSphere=207.0.0.7=20=20=20=20=20=20=20-=20NOTE:=20will=20need?= =?UTF-8?q?=20to=20submit=20patch=20to=20freemarker.org=20=20=20=2020552:?= =?UTF-8?q?=20Merged=20BRANCHES/V3.2=20to=20BRANCHES/V3.3=20(RECORD=20ONLY?= =?UTF-8?q?)=20=20=20=20=20=20=2020551:=20(RECORD=20ONLY)=20Merged=20BRANC?= =?UTF-8?q?HES/V3.3=20to=20BRANCHES/V3.2:=20=20=20=20=20=20=20=20=20=20200?= =?UTF-8?q?90:=20Dynamic=20models:=20minor=20improvements=20to=20Dictionar?= =?UTF-8?q?yModelType=20=20=20=2020553:=20Fix=20for=20escalated=20issue=20?= =?UTF-8?q?ALF-2856:=20Space=20returns=20to=20browse=20view=20after=20comp?= =?UTF-8?q?leting=20Add=20Content=20dialog;=20need=20a=20way=20to=20return?= =?UTF-8?q?=20to=20custom=20view=20(applied=20patch=20provided=20by=20cust?= =?UTF-8?q?omer).=20=20=20=2020554:=20Improvement=20to=20model=20delete=20?= =?UTF-8?q?validation=20(investigating=20intermittent=20failure=20of=20Rep?= =?UTF-8?q?oAdminServiceImplTest.testSimpleDynamicModelViaNodeService)=20?= =?UTF-8?q?=20=20=2020558:=20Merged=20DEV/BELARUS/V3.3-2010=5F06=5F08=20to?= =?UTF-8?q?=20V3.3=20=20=20=20=20=20=2020550:=20ALF-922:=20Mysql=20does=20?= =?UTF-8?q?not=20support=20unique=20keys=20that=20contain=20nulls=20as=20o?= =?UTF-8?q?ne=20would=20expect=20......=20duplicates=20in=20the=20alf=5Fac?= =?UTF-8?q?cess=5Fcontrol=5Fentry=20table=20=20=20=2020562:=20ALF-3177=20-?= =?UTF-8?q?=20security=20fix.=20=20=20=2020563:=20Merged=20BRANCHES/V3.2?= =?UTF-8?q?=20to=20BRANCHES/V3.3:=20=20=20=20=20=20=2019412:=20Fix=20for?= =?UTF-8?q?=20ALF-865=20"WCM=20/=20Cluster:=20unexpected=20error=20when=20?= =?UTF-8?q?concurrently=20submitting=20content"=20=20=20=20=20=20=20=20=20?= =?UTF-8?q?=20ALF-862=20"WCM=20submit=20execution=20will=20require=20locki?= =?UTF-8?q?ng=20in=20a=20clustered=20WCM=20authoring=20env"=20=20=20=20205?= =?UTF-8?q?64:=20Merged=20BRANCHES/V3.1=20to=20BRANCHES/V3.3:=20=20=20=20?= =?UTF-8?q?=20=20=2020542:=20Fixed=20ALF-3152:=20ImporterComponent=20trans?= =?UTF-8?q?action=20retry=20settings=20can=20cause=20IllegalArgumentExcept?= =?UTF-8?q?ion=20=20=20=2020568:=20Follow-up=20on=20fix=20ALF-3152.=20=20F?= =?UTF-8?q?ix=20jobLockService's=20retryWaitIncrementMs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@20572 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- config/alfresco/messages/webclient.properties | 1 + .../web-client-application-context.xml | 8 +- .../web/app/AlfrescoNavigationHandler.java | 23 +- .../web/app/servlet/AuthenticationHelper.java | 26 +- .../app/servlet/DefaultRemoteUserMapper.java | 1 + .../servlet/DefaultRemoteUserMapperTest.java | 1 + .../servlet/KerberosAuthenticationFilter.java | 5 +- .../app/servlet/NTLMAuthenticationFilter.java | 5 +- .../web/app/servlet/RemoteUserMapper.java | 38 - .../org/alfresco/web/bean/NavigationBean.java | 14 +- .../bean/content/DocumentDetailsDialog.java | 12 +- .../VersionedDocumentDetailsDialog.java | 30 +- .../web/bean/ml/MultilingualManageDialog.java | 11 +- .../web/bean/users/CreateUserWizard.java | 6 + .../web/bean/users/EditUserWizard.java | 9 +- .../web/bean/users/UsersBeanProperties.java | 699 +++++++++++------- .../web/bean/wcm/CreateWebContentWizard.java | 20 +- .../web/bean/wcm/DeleteFileDialog.java | 19 +- .../web/bean/wcm/EditWebContentWizard.java | 51 +- .../web/bean/wcm/PromptForWebFormDialog.java | 25 +- .../bean/wcm/RegenerateRenditionsWizard.java | 16 +- .../alfresco/web/bean/wcm/SubmitDialog.java | 83 ++- .../alfresco/web/forms/FormInstanceData.java | 19 +- .../web/forms/FormInstanceDataImpl.java | 92 ++- .../org/alfresco/web/forms/FormsService.java | 32 +- .../web/forms/xforms/Schema2XForms.java | 38 +- .../org/alfresco/web/ui/repo/tag/PageTag.java | 5 +- source/web/WEB-INF/faces-config-beans.xml | 4 + source/web/jsp/users/edit-user-details.jsp | 18 +- .../new-user-wizard/person-properties.jsp | 18 +- source/web/jsp/users/user-console.jsp | 2 +- source/web/jsp/users/users.jsp | 2 +- source/web/scripts/ajax/common.js | 28 + source/web/scripts/ajax/xforms.js | 76 +- 34 files changed, 883 insertions(+), 554 deletions(-) delete mode 100644 source/java/org/alfresco/web/app/servlet/RemoteUserMapper.java diff --git a/config/alfresco/messages/webclient.properties b/config/alfresco/messages/webclient.properties index 4f6f498e71..28e9b1a883 100644 --- a/config/alfresco/messages/webclient.properties +++ b/config/alfresco/messages/webclient.properties @@ -2041,6 +2041,7 @@ idle=Idle loading=Loading eg=e.g. click_to_edit=click to edit +please_select=Please select... # File Picker go_up=Go up diff --git a/config/alfresco/web-client-application-context.xml b/config/alfresco/web-client-application-context.xml index 9c9dcad9b2..a37851c8da 100644 --- a/config/alfresco/web-client-application-context.xml +++ b/config/alfresco/web-client-application-context.xml @@ -175,7 +175,7 @@ - org.alfresco.web.app.servlet.RemoteUserMapper + org.alfresco.repo.webdav.auth.RemoteUserMapper org.alfresco.repo.management.subsystems.ActivateableBean @@ -271,6 +271,12 @@ + + + + + + diff --git a/source/java/org/alfresco/web/app/AlfrescoNavigationHandler.java b/source/java/org/alfresco/web/app/AlfrescoNavigationHandler.java index 53b5f9297c..9fa7527b7d 100644 --- a/source/java/org/alfresco/web/app/AlfrescoNavigationHandler.java +++ b/source/java/org/alfresco/web/app/AlfrescoNavigationHandler.java @@ -510,6 +510,21 @@ public class AlfrescoNavigationHandler extends NavigationHandler return dispatchNode; } + protected void handleBrowseDispatch(FacesContext context, String fromAction, String outcome) + { + Node dispatchNode = null; + + NavigationBean navBean = (NavigationBean) context.getExternalContext().getSessionMap() + .get(NavigationBean.BEAN_NAME); + + if (navBean != null) + { + dispatchNode = navBean.getCurrentNode(); + } + + handleDispatch(context, fromAction, outcome, dispatchNode); + } + /** * Processes any dispatching that may need to occur * @@ -520,7 +535,11 @@ public class AlfrescoNavigationHandler extends NavigationHandler protected void handleDispatch(FacesContext context, String fromAction, String outcome) { Node dispatchNode = getDispatchContextNode(context); - + handleDispatch(context, fromAction, outcome, dispatchNode); + } + + private void handleDispatch(FacesContext context, String fromAction, String outcome, Node dispatchNode) + { if (dispatchNode != null) { if (logger.isDebugEnabled()) @@ -789,7 +808,7 @@ public class AlfrescoNavigationHandler extends NavigationHandler } else { - navigate(context, fromAction, overriddenOutcome); + handleBrowseDispatch(context, fromAction, overriddenOutcome); } } } diff --git a/source/java/org/alfresco/web/app/servlet/AuthenticationHelper.java b/source/java/org/alfresco/web/app/servlet/AuthenticationHelper.java index dd623cb6cf..9736628814 100644 --- a/source/java/org/alfresco/web/app/servlet/AuthenticationHelper.java +++ b/source/java/org/alfresco/web/app/servlet/AuthenticationHelper.java @@ -37,6 +37,7 @@ import org.alfresco.repo.security.authentication.AuthenticationException; import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.security.permissions.AccessDeniedException; import org.alfresco.repo.transaction.RetryingTransactionHelper; +import org.alfresco.repo.webdav.auth.RemoteUserMapper; import org.alfresco.service.ServiceRegistry; import org.alfresco.service.cmr.repository.InvalidNodeRefException; import org.alfresco.service.cmr.repository.NodeRef; @@ -273,11 +274,24 @@ public final class AuthenticationHelper HttpSession session = httpRequest.getSession(); try { - auth.validate(ticket, session.getId()); - - // We may have previously been authenticated via WebDAV so we may need to 'promote' the user object + // If we already have a cached user, make sure it is for the right ticket SessionUser user = (SessionUser)session.getAttribute(AuthenticationHelper.AUTHENTICATION_USER); - if (user == null || !(user instanceof User)) + if (user != null && !user.getTicket().equals(ticket)) + { + session.removeAttribute(AUTHENTICATION_USER); + if (!Application.inPortalServer()) + { + session.invalidate(); + session = httpRequest.getSession(); + } + user = null; + } + + // Validate the ticket and associate it with the session + auth.validate(ticket, session.getId()); + + // Cache a new user in the session if required + if (user == null) { setUser(context, httpRequest, auth.getCurrentUserName(), ticket, false); } @@ -285,6 +299,10 @@ public final class AuthenticationHelper catch (AuthenticationException authErr) { session.removeAttribute(AUTHENTICATION_USER); + if (!Application.inPortalServer()) + { + session.invalidate(); + } return AuthenticationStatus.Failure; } catch (Throwable e) diff --git a/source/java/org/alfresco/web/app/servlet/DefaultRemoteUserMapper.java b/source/java/org/alfresco/web/app/servlet/DefaultRemoteUserMapper.java index 481400a4d5..c28d868923 100644 --- a/source/java/org/alfresco/web/app/servlet/DefaultRemoteUserMapper.java +++ b/source/java/org/alfresco/web/app/servlet/DefaultRemoteUserMapper.java @@ -28,6 +28,7 @@ import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; import org.alfresco.service.cmr.security.PersonService; +import org.alfresco.repo.webdav.auth.RemoteUserMapper; /** * A default {@link RemoteUserMapper} implementation. Extracts a user ID using * {@link HttpServletRequest#getRemoteUser()} and optionally from a configured request header. If there is no configured diff --git a/source/java/org/alfresco/web/app/servlet/DefaultRemoteUserMapperTest.java b/source/java/org/alfresco/web/app/servlet/DefaultRemoteUserMapperTest.java index efea132636..5de9ada8fe 100644 --- a/source/java/org/alfresco/web/app/servlet/DefaultRemoteUserMapperTest.java +++ b/source/java/org/alfresco/web/app/servlet/DefaultRemoteUserMapperTest.java @@ -32,6 +32,7 @@ import javax.servlet.http.HttpServletRequest; import org.alfresco.repo.management.subsystems.AbstractChainedSubsystemTest; import org.alfresco.repo.management.subsystems.ChildApplicationContextFactory; import org.alfresco.repo.management.subsystems.DefaultChildApplicationContextManager; +import org.alfresco.repo.webdav.auth.RemoteUserMapper; import org.alfresco.util.ApplicationContextHelper; import org.springframework.context.ApplicationContext; diff --git a/source/java/org/alfresco/web/app/servlet/KerberosAuthenticationFilter.java b/source/java/org/alfresco/web/app/servlet/KerberosAuthenticationFilter.java index c52b0ef4b8..9413685e52 100644 --- a/source/java/org/alfresco/web/app/servlet/KerberosAuthenticationFilter.java +++ b/source/java/org/alfresco/web/app/servlet/KerberosAuthenticationFilter.java @@ -130,9 +130,10 @@ public class KerberosAuthenticationFilter extends BaseKerberosAuthenticationFilt throws IOException { // If the original URL requested was the login page then redirect to the browse view - if (userInit || req.getRequestURI().endsWith(getLoginPage())) + String requestURI = req.getRequestURI(); + if (requestURI.startsWith(req.getContextPath() + BaseServlet.FACES_SERVLET) && (userInit || requestURI.endsWith(getLoginPage()))) { - if (logger.isDebugEnabled() && req.getRequestURI().endsWith(getLoginPage())) + if (logger.isDebugEnabled() && requestURI.endsWith(getLoginPage())) logger.debug("Login page requested - redirecting to initially configured page"); if (logger.isDebugEnabled() && userInit) logger.debug("Session reinitialised - redirecting to initially configured page"); diff --git a/source/java/org/alfresco/web/app/servlet/NTLMAuthenticationFilter.java b/source/java/org/alfresco/web/app/servlet/NTLMAuthenticationFilter.java index 3ccb33d8f6..34d72cc0b3 100644 --- a/source/java/org/alfresco/web/app/servlet/NTLMAuthenticationFilter.java +++ b/source/java/org/alfresco/web/app/servlet/NTLMAuthenticationFilter.java @@ -123,9 +123,10 @@ public class NTLMAuthenticationFilter extends BaseNTLMAuthenticationFilter throws IOException { // If the original URL requested was the login page then redirect to the browse view - if (userInit || req.getRequestURI().endsWith(getLoginPage())) + String requestURI = req.getRequestURI(); + if (requestURI.startsWith(req.getContextPath() + BaseServlet.FACES_SERVLET) && (userInit || requestURI.endsWith(getLoginPage()))) { - if (logger.isDebugEnabled() && req.getRequestURI().endsWith(getLoginPage())) + if (logger.isDebugEnabled() && requestURI.endsWith(getLoginPage())) logger.debug("Login page requested - redirecting to initially configured page"); if (logger.isDebugEnabled() && userInit) logger.debug("Session reinitialised - redirecting to initially configured page"); diff --git a/source/java/org/alfresco/web/app/servlet/RemoteUserMapper.java b/source/java/org/alfresco/web/app/servlet/RemoteUserMapper.java deleted file mode 100644 index 745fb4ec8a..0000000000 --- a/source/java/org/alfresco/web/app/servlet/RemoteUserMapper.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ -package org.alfresco.web.app.servlet; - -import javax.servlet.http.HttpServletRequest; - -/** - * An interface for objects capable of extracting an externally authenticated user ID from an HTTP request. - * - * @author dward - */ -public interface RemoteUserMapper -{ - /** - * Gets an externally authenticated user ID from an HTTP request. - * - * @param request - * the request - * @return the user ID or null if the user is unauthenticated - */ - public String getRemoteUser(HttpServletRequest request); -} diff --git a/source/java/org/alfresco/web/bean/NavigationBean.java b/source/java/org/alfresco/web/bean/NavigationBean.java index fae2635d7e..906f83f5e8 100644 --- a/source/java/org/alfresco/web/bean/NavigationBean.java +++ b/source/java/org/alfresco/web/bean/NavigationBean.java @@ -1020,13 +1020,19 @@ public class NavigationBean implements Serializable } /** - * @return true if users can configure their own settings and password in the User Console + * @return true if users can configure their own settings in the User Console */ public boolean isAllowUserConfig() { - // For correct behaviour, we ask the authentication chain whether this particular user is mutable - return this.clientConfig.getAllowUserConfig() - && this.authService.isAuthenticationMutable(this.authService.getCurrentUserName()); + return this.clientConfig.getAllowUserConfig(); + } + + /** + * @return true if a users can modify the password set against their authentication + */ + public boolean isAllowUserChangePassword() + { + return this.authService.isAuthenticationMutable(this.authService.getCurrentUserName()); } diff --git a/source/java/org/alfresco/web/bean/content/DocumentDetailsDialog.java b/source/java/org/alfresco/web/bean/content/DocumentDetailsDialog.java index cfa8f4850c..c2e7901ffc 100644 --- a/source/java/org/alfresco/web/bean/content/DocumentDetailsDialog.java +++ b/source/java/org/alfresco/web/bean/content/DocumentDetailsDialog.java @@ -22,7 +22,6 @@ import java.io.Serializable; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Locale; @@ -39,7 +38,6 @@ import org.alfresco.model.ContentModel; import org.alfresco.repo.content.MimetypeMap; import org.alfresco.repo.transaction.RetryingTransactionHelper; import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; -import org.alfresco.repo.version.common.VersionLabelComparator; import org.alfresco.service.cmr.coci.CheckOutCheckInService; import org.alfresco.service.cmr.lock.LockService; import org.alfresco.service.cmr.ml.ContentFilterLanguagesService; @@ -391,15 +389,14 @@ public class DocumentDetailsDialog extends BaseDetailsBean implements Navigatio * * @return List of editions */ - @SuppressWarnings("unchecked") + @SuppressWarnings("unused") private List initEditionHistory() { // get the mlContainer NodeRef mlContainer = getDocumentMlContainer().getNodeRef(); - // get all editions and sort them ascending according their version label + // get all editions (in descending order - ie. most recent first) List orderedEditionList = new ArrayList(getEditionService().getEditions(mlContainer).getAllVersions()); - Collections.sort(orderedEditionList, new VersionLabelComparator()); // the list of Single Edition Bean to return editionHistory = new ArrayList(orderedEditionList.size()); @@ -449,11 +446,10 @@ public class DocumentDetailsDialog extends BaseDetailsBean implements Navigatio // add each translation in the SingleEditionBean for (VersionHistory versionHistory : translationHistories) { - // get the list of versions and sort them ascending according their version label + // get the list of versions (in descending order - ie. most recent first) List orderedVersions = new ArrayList(versionHistory.getAllVersions()); - Collections.sort(orderedVersions, new VersionLabelComparator()); - // the last version is the first version of the list + // the last version (ie. most recent) is the first version of the list Version lastVersion = orderedVersions.get(0); // get the properties of the lastVersion diff --git a/source/java/org/alfresco/web/bean/content/VersionedDocumentDetailsDialog.java b/source/java/org/alfresco/web/bean/content/VersionedDocumentDetailsDialog.java index bfa8fec46a..e870349ea7 100644 --- a/source/java/org/alfresco/web/bean/content/VersionedDocumentDetailsDialog.java +++ b/source/java/org/alfresco/web/bean/content/VersionedDocumentDetailsDialog.java @@ -31,9 +31,8 @@ import java.util.Map; import javax.faces.context.FacesContext; import javax.faces.event.ActionEvent; -import org.springframework.extensions.surf.util.I18NUtil; import org.alfresco.model.ContentModel; -import org.alfresco.repo.version.common.VersionLabelComparator; +import org.alfresco.repo.version.common.VersionHistoryImpl.VersionComparatorDesc; import org.alfresco.repo.web.scripts.FileTypeImageUtils; import org.alfresco.service.cmr.ml.ContentFilterLanguagesService; import org.alfresco.service.cmr.ml.EditionService; @@ -45,7 +44,6 @@ import org.alfresco.service.cmr.version.Version; import org.alfresco.service.cmr.version.VersionHistory; import org.alfresco.service.cmr.version.VersionService; import org.alfresco.service.namespace.QName; -import org.springframework.extensions.surf.util.ParameterCheck; import org.alfresco.web.app.Application; import org.alfresco.web.app.servlet.DownloadContentServlet; import org.alfresco.web.bean.BrowseBean; @@ -54,6 +52,8 @@ import org.alfresco.web.bean.repository.Node; import org.alfresco.web.bean.repository.Repository; import org.alfresco.web.ui.common.Utils; import org.alfresco.web.ui.common.component.UIActionLink; +import org.springframework.extensions.surf.util.I18NUtil; +import org.springframework.extensions.surf.util.ParameterCheck; /** * Bean with generic function helping the rendering of the versioned properties @@ -71,7 +71,7 @@ public class VersionedDocumentDetailsDialog implements Serializable transient private MultilingualContentService multilingualContentService; transient private ContentFilterLanguagesService contentFilterLanguagesService; - private static final Comparator VERSION_LABEL_COMPARATOR = new VersionLabelComparator(); + private static final Comparator VERSION_COMPARATOR_DESC = new VersionComparatorDesc(); /** Determine if the version is a translation of a old edition */ private boolean fromPreviousEditon; @@ -196,7 +196,7 @@ public class VersionedDocumentDetailsDialog implements Serializable } else { - Collections.sort(nextVersions, VERSION_LABEL_COMPARATOR); + Collections.sort(nextVersions, VERSION_COMPARATOR_DESC); this.documentVersion = nextVersions.get(0); } } @@ -223,12 +223,10 @@ public class VersionedDocumentDetailsDialog implements Serializable { Version prevVersion = this.versionHistory.getPredecessor(this.documentVersion); - // if the version history doesn't contains predecessor, get the last version + // if the version history doesn't contains predecessor, get the last version (ie. most recent) if(prevVersion == null) { List allVersions = new ArrayList(this.versionHistory.getAllVersions()); - Collections.sort(allVersions, VERSION_LABEL_COMPARATOR); - this.documentVersion = allVersions.get(0); } else @@ -265,14 +263,13 @@ public class VersionedDocumentDetailsDialog implements Serializable { translationNodeRef = new HashMap(translationsList.size()); - // get the last version of the translation in the given lang of the edition + // get the last (most recent) version of the translation in the given lang of the edition for (VersionHistory history : translationsList) { - // get the list of versions and sort them ascending according their version label + // get the list of versions (in descending order - ie. most recent first) List orderedVersions = new ArrayList(history.getAllVersions()); - Collections.sort(orderedVersions, VERSION_LABEL_COMPARATOR); - // the last version is the first version of the list + // the last (most recent) version is the first version of the list Version lastVersion = orderedVersions.get(0); // fill the list of translation @@ -471,7 +468,7 @@ public class VersionedDocumentDetailsDialog implements Serializable } /** - * Util method which return the last version of a translation of a given edition of a mlContainer according its language + * Util method which return the last (most recent) version of a translation of a given edition of a mlContainer according its language */ @SuppressWarnings("unchecked") private Version getBrowsingVersionForMLContainer(NodeRef document, String editionLabel, String lang) @@ -489,14 +486,13 @@ public class VersionedDocumentDetailsDialog implements Serializable { Version versionToReturn = null; - // get the last version of the translation in the given lang of the edition + // get the last (most recent) version of the translation in the given lang of the edition for (VersionHistory history : translations) { - // get the list of versions and sort them ascending according their version label + // get the list of versions (in descending order - ie. most recent first) List orderedVersions = new ArrayList(history.getAllVersions()); - Collections.sort(orderedVersions, VERSION_LABEL_COMPARATOR); - // the last version is the first version of the list + // the last version (ie. most recent) is the first version of the list Version lastVersion = orderedVersions.get(0); if(lastVersion != null) diff --git a/source/java/org/alfresco/web/bean/ml/MultilingualManageDialog.java b/source/java/org/alfresco/web/bean/ml/MultilingualManageDialog.java index a70ff9f73b..3904d987cc 100644 --- a/source/java/org/alfresco/web/bean/ml/MultilingualManageDialog.java +++ b/source/java/org/alfresco/web/bean/ml/MultilingualManageDialog.java @@ -21,7 +21,6 @@ package org.alfresco.web.bean.ml; import java.io.Serializable; import java.text.MessageFormat; import java.util.ArrayList; -import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Locale; @@ -31,7 +30,6 @@ import javax.faces.context.FacesContext; import javax.faces.event.ActionEvent; import org.alfresco.model.ContentModel; -import org.alfresco.repo.version.common.VersionLabelComparator; import org.alfresco.service.cmr.ml.ContentFilterLanguagesService; import org.alfresco.service.cmr.ml.EditionService; import org.alfresco.service.cmr.ml.MultilingualContentService; @@ -427,15 +425,13 @@ public class MultilingualManageDialog extends BaseDialogBean * * @return List of editions */ - @SuppressWarnings("unchecked") private List initEditionHistory() { // get the mlContainer NodeRef mlContainer = getDocumentMlContainer().getNodeRef(); - // get all editions and sort them ascending according their version label + // get all editions (in descending order - ie. most recent first) List orderedEditionList = new ArrayList(getEditionService().getEditions(mlContainer).getAllVersions()); - Collections.sort(orderedEditionList, new VersionLabelComparator()); // the list of Single Edition Bean to return editionHistory = new ArrayList(orderedEditionList.size()); @@ -498,11 +494,10 @@ public class MultilingualManageDialog extends BaseDialogBean } } - // get the list of versions and sort them ascending according their version label + // get the list of versions (in descending order - ie. most recent first) List orderedVersions = new ArrayList(versionHistory.getAllVersions()); - Collections.sort(orderedVersions, new VersionLabelComparator()); - // the last version is the first version of the list + // the last version (ie. most recent) is the first version of the list Version lastVersion = orderedVersions.get(0); // get the properties of the lastVersion diff --git a/source/java/org/alfresco/web/bean/users/CreateUserWizard.java b/source/java/org/alfresco/web/bean/users/CreateUserWizard.java index 7ec6198bdc..b16804ba25 100644 --- a/source/java/org/alfresco/web/bean/users/CreateUserWizard.java +++ b/source/java/org/alfresco/web/bean/users/CreateUserWizard.java @@ -20,6 +20,7 @@ package org.alfresco.web.bean.users; import java.io.Serializable; import java.text.MessageFormat; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -976,4 +977,9 @@ public class CreateUserWizard extends BaseWizardBean return true; } + + public Map getPersonPropertiesImmutability() + { + return Collections.EMPTY_MAP; + } } diff --git a/source/java/org/alfresco/web/bean/users/EditUserWizard.java b/source/java/org/alfresco/web/bean/users/EditUserWizard.java index a585d6d8eb..7ec8ec3585 100644 --- a/source/java/org/alfresco/web/bean/users/EditUserWizard.java +++ b/source/java/org/alfresco/web/bean/users/EditUserWizard.java @@ -220,10 +220,17 @@ public class EditUserWizard extends CreateUserWizard ReportedException.throwIfNecessary(e); } - if (outcome == null) { + if (outcome == null) + { this.isFinished = false; } return outcome; } + + @Override + public Map getPersonPropertiesImmutability() + { + return this.properties.getImmutability(); + } } diff --git a/source/java/org/alfresco/web/bean/users/UsersBeanProperties.java b/source/java/org/alfresco/web/bean/users/UsersBeanProperties.java index 36d0a7ba43..f9ad668c61 100644 --- a/source/java/org/alfresco/web/bean/users/UsersBeanProperties.java +++ b/source/java/org/alfresco/web/bean/users/UsersBeanProperties.java @@ -19,11 +19,17 @@ package org.alfresco.web.bean.users; import java.io.Serializable; +import java.util.Collection; import java.util.List; +import java.util.Map; +import java.util.Set; import javax.faces.context.FacesContext; import org.alfresco.model.ContentModel; +import org.alfresco.repo.security.sync.UserRegistrySynchronizer; +import org.alfresco.repo.transaction.RetryingTransactionHelper; +import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; import org.alfresco.service.cmr.repository.AssociationRef; import org.alfresco.service.cmr.repository.ContentReader; import org.alfresco.service.cmr.repository.ContentService; @@ -33,301 +39,450 @@ import org.alfresco.service.cmr.search.SearchService; import org.alfresco.service.cmr.security.MutableAuthenticationService; import org.alfresco.service.cmr.security.PersonService; import org.alfresco.service.cmr.usage.ContentUsageService; +import org.alfresco.service.namespace.NamespaceService; +import org.alfresco.service.namespace.QName; import org.alfresco.web.app.servlet.DownloadContentServlet; import org.alfresco.web.app.servlet.FacesHelper; import org.alfresco.web.bean.repository.Node; import org.alfresco.web.bean.repository.Repository; +import org.alfresco.web.ui.common.ReportedException; import org.alfresco.web.ui.common.Utils; import org.alfresco.web.ui.common.component.data.UIRichList; +import org.springframework.web.jsf.FacesContextUtils; +/** + * Bean holding the properties for a Person node. + * + * Used by the Create/EditUserWizard, UsersDialog and EditUserDetailsDetails to maitain user state during dialog. + * + * Also provides access to a map of the properties to mutability which is used to disable appropriate controls on edit + * dialogs if properties are externally mapped to LDAP or similar. + */ public class UsersBeanProperties implements Serializable { - private static final long serialVersionUID = 8874192805959149144L; - - /** NodeService bean reference */ - transient private NodeService nodeService; - - /** SearchService bean reference */ - transient private SearchService searchService; - - /** AuthenticationService bean reference */ - transient private MutableAuthenticationService authenticationService; - - /** PersonService bean reference */ - transient private PersonService personService; - - /** ContentUsageService bean reference */ - transient private ContentUsageService contentUsageService; - - - /** Component reference for Users RichList control */ - private UIRichList usersRichList; - - /** action context */ - private Node person = null; - - private String password = null; - private String oldPassword = null; - private String confirm = null; - private String searchCriteria = null; - private String userName = null; - - // ------------------------------------------------------------------------------ - // Bean property getters and setters - - /** - * @return the nodeService - */ - public NodeService getNodeService() - { - //check for null for cluster environment - if (nodeService == null) - { - nodeService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getNodeService(); - } - return nodeService; - } - - /** - * @return the searchService - */ - public SearchService getSearchService() - { - //check for null for cluster environment - if (searchService == null) - { - searchService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getSearchService(); - } - - return searchService; - } - - /** - * @return the authenticationService - */ - public MutableAuthenticationService getAuthenticationService() - { - //check for null for cluster environment - if (authenticationService == null) - { - authenticationService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getAuthenticationService(); - } - return authenticationService; - } - - /** - * @return the personService - */ - public PersonService getPersonService() - { - //check for null for cluster environment - if(personService == null) - { - personService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getPersonService(); - } - return personService; - } - - - /** - *@return contentUsageService - */ - public ContentUsageService getContentUsageService() - { - //check for null for cluster environment - if(contentUsageService == null) - { - contentUsageService = (ContentUsageService) FacesHelper.getManagedBean(FacesContext.getCurrentInstance(), "ContentUsageService"); - } - return contentUsageService; - } + private static final long serialVersionUID = 8874192805959149144L; + + /** NodeService bean reference */ + transient private NodeService nodeService; + + /** SearchService bean reference */ + transient private SearchService searchService; + + /** AuthenticationService bean reference */ + transient private MutableAuthenticationService authenticationService; + + /** PersonService bean reference */ + transient private PersonService personService; + + /** ContentUsageService bean reference */ + transient private ContentUsageService contentUsageService; + + /** userRegistrySynchronizer bean reference */ + transient private UserRegistrySynchronizer userRegistrySynchronizer; + + /** Component reference for Users RichList control */ + private UIRichList usersRichList; + + /** action context */ + private Node person = null; + private String password = null; + private String oldPassword = null; + private String confirm = null; + private String searchCriteria = null; + private String userName = null; + private Map immutabilty = null; + + + // ------------------------------------------------------------------------------ + // Bean property getters and setters /** - * @param nodeService The NodeService to set. - */ - public void setNodeService(NodeService nodeService) - { - this.nodeService = nodeService; - } + * @return the nodeService + */ + public NodeService getNodeService() + { + if (nodeService == null) + { + nodeService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getNodeService(); + } + return nodeService; + } - /** - * @param searchService the search service - */ - public void setSearchService(SearchService searchService) - { - this.searchService = searchService; - } + /** + * @return the searchService + */ + public SearchService getSearchService() + { + if (searchService == null) + { + searchService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getSearchService(); + } + return searchService; + } - /** - * @param authenticationService The AuthenticationService to set. - */ - public void setAuthenticationService(MutableAuthenticationService authenticationService) - { - this.authenticationService = authenticationService; - } + /** + * @return the authenticationService + */ + public MutableAuthenticationService getAuthenticationService() + { + if (authenticationService == null) + { + authenticationService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getAuthenticationService(); + } + return authenticationService; + } - /** - * @param personService The PersonService to set. - */ - public void setPersonService(PersonService personService) - { - this.personService = personService; - } - - /** - * @param contentUsageService The ContentUsageService to set. - */ - public void setContentUsageService(ContentUsageService contentUsageService) - { - this.contentUsageService = contentUsageService; - } + /** + * @return the personService + */ + public PersonService getPersonService() + { + if (personService == null) + { + personService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getPersonService(); + } + return personService; + } - /** - * @return Returns the usersRichList. - */ - public UIRichList getUsersRichList() - { - return this.usersRichList; - } + /** + * @return contentUsageService + */ + public ContentUsageService getContentUsageService() + { + if (contentUsageService == null) + { + contentUsageService = (ContentUsageService) FacesHelper.getManagedBean(FacesContext.getCurrentInstance(), "ContentUsageService"); + } + return contentUsageService; + } + + /** + * @return userRegistrySynchronizer + */ + public UserRegistrySynchronizer getUserRegistrySynchronizer() + { + if (userRegistrySynchronizer == null) + { + userRegistrySynchronizer = (UserRegistrySynchronizer)FacesContextUtils.getRequiredWebApplicationContext( + FacesContext.getCurrentInstance()).getBean("userRegistrySynchronizer"); + } + return userRegistrySynchronizer; + } + + /** + * @param nodeService The NodeService to set. + */ + public void setNodeService(NodeService nodeService) + { + this.nodeService = nodeService; + } - /** - * @param usersRichList The usersRichList to set. - */ - public void setUsersRichList(UIRichList usersRichList) - { - this.usersRichList = usersRichList; - } + /** + * @param searchServiceq the search service + */ + public void setSearchService(SearchService searchService) + { + this.searchService = searchService; + } - /** - * @return Returns the search criteria - */ - public String getSearchCriteria() - { - return searchCriteria; - } + /** + * @param authenticationService The AuthenticationService to set. + */ + public void setAuthenticationService(MutableAuthenticationService authenticationService) + { + this.authenticationService = authenticationService; + } - /** - * @param searchCriteria The search criteria to select - */ - public void setSearchCriteria(String searchCriteria) - { - this.searchCriteria = searchCriteria; - } + /** + * @param personService The PersonService to set. + */ + public void setPersonService(PersonService personService) + { + this.personService = personService; + } - /** - * @return Returns the confirm password. - */ - public String getConfirm() - { - return this.confirm; - } + /** + * @param contentUsageService The ContentUsageService to set. + */ + public void setContentUsageService(ContentUsageService contentUsageService) + { + this.contentUsageService = contentUsageService; + } + + /** + * @param userRegistrySynchronizer + */ + public void setUserRegistrySynchronizer(UserRegistrySynchronizer userRegistrySynchronizer) + { + this.userRegistrySynchronizer = userRegistrySynchronizer; + } - /** - * @param confirm The confirm password to set. - */ - public void setConfirm(String confirm) - { - this.confirm = confirm; - } + /** + * @return Returns the usersRichList. + */ + public UIRichList getUsersRichList() + { + return this.usersRichList; + } - /** - * @return Returns the password. - */ - public String getPassword() - { - return this.password; - } + /** + * @param usersRichList The usersRichList to set. + */ + public void setUsersRichList(UIRichList usersRichList) + { + this.usersRichList = usersRichList; + } - /** - * @param password The password to set. - */ - public void setPassword(String password) - { - this.password = password; - } - - /** - * @return Returns the old password. - */ - public String getOldPassword() - { - return this.oldPassword; - } + /** + * @return Returns the search criteria + */ + public String getSearchCriteria() + { + return searchCriteria; + } - /** - * @param oldPassword The old password to set. - */ - public void setOldPassword(String oldPassword) - { - this.oldPassword = oldPassword; - } + /** + * @param searchCriteria The search criteria to select + */ + public void setSearchCriteria(String searchCriteria) + { + this.searchCriteria = searchCriteria; + } - /** - * @return Returns the person context. - */ - public Node getPerson() - { - return this.person; - } + /** + * @return Returns the confirm password. + */ + public String getConfirm() + { + return this.confirm; + } - /** - * @param person The person context to set. - */ - public void setPerson(Node person) - { - this.person = person; - this.userName = (String)person.getProperties().get(ContentModel.PROP_USERNAME); - } - - public Long getUserUsage(String userName) - { - long usage = getContentUsageService().getUserUsage(userName); - return (usage == -1 ? null : usage); - } - - public Long getUserUsage() - { - long usage = getContentUsageService().getUserUsage(this.userName); - return (usage == -1 ? null : usage); - } - - public Long getUserQuota() - { - long quota = getContentUsageService().getUserQuota(this.userName); - return (quota == -1 ? null : quota); - } - - public boolean getUsagesEnabled() - { - return getContentUsageService().getEnabled(); - } - - public String getPersonDescription() - { - ContentService cs = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getContentService(); - ContentReader reader = cs.getReader(this.person.getNodeRef(), ContentModel.PROP_PERSONDESC); - if (reader != null && reader.exists()) - { - return Utils.stripUnsafeHTMLTags(reader.getContentString()).replace("\r\n", "

"); - } - else - { - return null; - } - } - - public String getAvatarUrl() - { - String avatarUrl = null; - - List refs = getNodeService().getTargetAssocs(this.person.getNodeRef(), ContentModel.ASSOC_AVATAR); - if (refs.size() == 1) - { - NodeRef photoRef = refs.get(0).getTargetRef(); - String name = (String)getNodeService().getProperty(photoRef, ContentModel.PROP_NAME); - avatarUrl = DownloadContentServlet.generateBrowserURL(photoRef, name); - } - - return avatarUrl; - } + /** + * @param confirm The confirm password to set. + */ + public void setConfirm(String confirm) + { + this.confirm = confirm; + } + + /** + * @return Returns the password. + */ + public String getPassword() + { + return this.password; + } + + /** + * @param password The password to set. + */ + public void setPassword(String password) + { + this.password = password; + } + + /** + * @return Returns the old password. + */ + public String getOldPassword() + { + return this.oldPassword; + } + + /** + * @param oldPassword The old password to set. + */ + public void setOldPassword(String oldPassword) + { + this.oldPassword = oldPassword; + } + + /** + * @return Returns the person context. + */ + public Node getPerson() + { + return this.person; + } + + /** + * @param person The person context to set. + */ + public void setPerson(final Node p) + { + // perform the set in a txn as certain bean calls require it + FacesContext context = FacesContext.getCurrentInstance(); + RetryingTransactionHelper txnHelper = Repository.getRetryingTransactionHelper(context); + RetryingTransactionCallback callback = new RetryingTransactionCallback() + { + public Object execute() throws Throwable + { + person = p; + userName = (String)person.getProperties().get(ContentModel.PROP_USERNAME); + + // rebuild the property immutability map helper object + immutabilty = new PropertyImmutabilityMap( + getUserRegistrySynchronizer().getPersonMappedProperties(userName)); + + return null; + } + }; + try + { + txnHelper.doInTransaction(callback, false); + } + catch (Throwable e) + { + // reset the flag so we can re-attempt the operation + if (e instanceof ReportedException == false) + { + Utils.addErrorMessage(e.getMessage(), e); + } + ReportedException.throwIfNecessary(e); + } + } + + public Long getUserUsage(String userName) + { + long usage = getContentUsageService().getUserUsage(userName); + return (usage == -1 ? null : usage); + } + + public Long getUserUsage() + { + long usage = getContentUsageService().getUserUsage(this.userName); + return (usage == -1 ? null : usage); + } + + public Long getUserQuota() + { + long quota = getContentUsageService().getUserQuota(this.userName); + return (quota == -1 ? null : quota); + } + + public boolean getUsagesEnabled() + { + return getContentUsageService().getEnabled(); + } + + public String getPersonDescription() + { + ContentService cs = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getContentService(); + ContentReader reader = cs.getReader(this.person.getNodeRef(), ContentModel.PROP_PERSONDESC); + if (reader != null && reader.exists()) + { + return Utils.stripUnsafeHTMLTags(reader.getContentString()).replace("\r\n", "

"); + } + else + { + return null; + } + } + + public String getAvatarUrl() + { + String avatarUrl = null; + + List refs = getNodeService().getTargetAssocs(this.person.getNodeRef(), ContentModel.ASSOC_AVATAR); + if (refs.size() == 1) + { + NodeRef photoRef = refs.get(0).getTargetRef(); + String name = (String) getNodeService().getProperty(photoRef, ContentModel.PROP_NAME); + avatarUrl = DownloadContentServlet.generateBrowserURL(photoRef, name); + } + + return avatarUrl; + } + + public Map getImmutability() + { + return this.immutabilty; + } + + /** + * Map of person property to immutability + * The Map interface is implemented to allow JSF expressions such as + * #{DialogBean.bean.properties.immutability.propertyname} + */ + public class PropertyImmutabilityMap implements Map, Serializable + { + final private Set props; + + PropertyImmutabilityMap(Set props) + { + this.props = props; + } + + public void clear() + { + } + + public boolean containsKey(Object k) + { + boolean contains = false; + if (k instanceof String && ((String)k).length() != 0) + { + String s = (String)k; + if (s.charAt(0) == '{' && s.indexOf('}') != -1) + { + contains = this.props.contains(k); + } + else + { + // simple property name - assume and apply CM namespace + contains = this.props.contains(QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, s)); + } + } + return contains; + } + + public boolean containsValue(Object v) + { + return false; + } + + public Set> entrySet() + { + return null; + } + + public Boolean get(Object k) + { + return containsKey(k); + } + + public boolean isEmpty() + { + return this.props.size() != 0; + } + + public Set keySet() + { + return null; + } + + public Boolean put(String k, Boolean v) + { + return null; + } + + public void putAll(Map m) + { + } + + public Boolean remove(Object k) + { + return null; + } + + public int size() + { + return this.props.size(); + } + + public Collection values() + { + return null; + } + } } diff --git a/source/java/org/alfresco/web/bean/wcm/CreateWebContentWizard.java b/source/java/org/alfresco/web/bean/wcm/CreateWebContentWizard.java index f2d35e2b15..fa4ad3f206 100644 --- a/source/java/org/alfresco/web/bean/wcm/CreateWebContentWizard.java +++ b/source/java/org/alfresco/web/bean/wcm/CreateWebContentWizard.java @@ -464,11 +464,21 @@ public class CreateWebContentWizard extends CreateContentWizard if (MimetypeMap.MIMETYPE_XML.equals(this.mimeType) && this.formName != null) { - this.formInstanceData = getFormsService().getFormInstanceData(-1, this.createdPath); - this.renditions = this.formInstanceData.getRenditions(); - if (logger.isDebugEnabled()) - logger.debug("reset form instance data " + this.formInstanceData.getName() + - " and " + this.renditions.size() + " rendition(s) to main store"); + try + { + this.formInstanceData = getFormsService().getFormInstanceData(-1, this.createdPath); + this.renditions = this.formInstanceData.getRenditions(); + + if (logger.isDebugEnabled()) + { + logger.debug("reset form instance data " + this.formInstanceData.getName() + + " and " + this.renditions.size() + " rendition(s) to main store"); + } + } + catch (FormNotFoundException fnfe) + { + logger.warn(fnfe); + } } this.avmBrowseBean.setAvmActionNode(new AVMNode(this.getAvmService().lookup(-1, this.createdPath))); diff --git a/source/java/org/alfresco/web/bean/wcm/DeleteFileDialog.java b/source/java/org/alfresco/web/bean/wcm/DeleteFileDialog.java index 6005b33936..8ba3b37734 100644 --- a/source/java/org/alfresco/web/bean/wcm/DeleteFileDialog.java +++ b/source/java/org/alfresco/web/bean/wcm/DeleteFileDialog.java @@ -33,6 +33,7 @@ import org.alfresco.web.app.servlet.FacesHelper; import org.alfresco.web.bean.dialog.BaseDialogBean; import org.alfresco.web.bean.repository.Repository; import org.alfresco.web.forms.*; +import org.alfresco.web.ui.common.Utils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -189,7 +190,6 @@ public class DeleteFileDialog extends BaseDialogBean node.getName(), fid.getName(), fid.getRenditions().size() - 1); - } catch (FileNotFoundException fnfe) { @@ -198,11 +198,18 @@ public class DeleteFileDialog extends BaseDialogBean } else if (node.hasAspect(WCMAppModel.ASPECT_FORM_INSTANCE_DATA)) { - final FormInstanceData fid = this.getFormsService().getFormInstanceData(node.getNodeRef()); - return MessageFormat.format(Application.getMessage(FacesContext.getCurrentInstance(), - "delete_form_instance_data_confirm"), - fid.getName(), - fid.getRenditions().size()); + try + { + final FormInstanceData fid = this.getFormsService().getFormInstanceData(node.getNodeRef()); + return MessageFormat.format(Application.getMessage(FacesContext.getCurrentInstance(), + "delete_form_instance_data_confirm"), + fid.getName(), + fid.getRenditions().size()); + } + catch (FormNotFoundException fnfe) + { + // ignore + } } return MessageFormat.format(Application.getMessage(FacesContext.getCurrentInstance(), "delete_avm_file_confirm"), diff --git a/source/java/org/alfresco/web/bean/wcm/EditWebContentWizard.java b/source/java/org/alfresco/web/bean/wcm/EditWebContentWizard.java index fde3d7089b..c4468a5117 100644 --- a/source/java/org/alfresco/web/bean/wcm/EditWebContentWizard.java +++ b/source/java/org/alfresco/web/bean/wcm/EditWebContentWizard.java @@ -18,10 +18,11 @@ */ package org.alfresco.web.bean.wcm; -import java.util.ArrayList; +import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.Set; import org.alfresco.repo.content.MimetypeMap; import org.alfresco.service.cmr.avm.locking.AVMLock; @@ -48,7 +49,7 @@ public class EditWebContentWizard extends CreateWebContentWizard private AVMNode avmNode; private Form form; - protected List locksPresentAtInit = null; + protected Set existingLocks = null; // ------------------------------------------------------------------------------ // Wizard implementation @@ -67,11 +68,14 @@ public class EditWebContentWizard extends CreateWebContentWizard logger.debug("path is " + this.avmNode.getPath()); this.createdPath = AVMUtil.getCorrespondingPathInPreviewStore(this.avmNode.getPath()); - this.formInstanceData = this.getFormsService().getFormInstanceData(-1, this.createdPath); final WebProject webProject = new WebProject(this.createdPath); + try { + this.formInstanceData = this.getFormsService().getFormInstanceData(-1, this.createdPath); this.formName = this.formInstanceData.getForm().getName(); + this.fileName = this.formInstanceData.getName(); + this.form = webProject.getForm(this.formName); } catch (FormNotFoundException fnfe) @@ -79,16 +83,15 @@ public class EditWebContentWizard extends CreateWebContentWizard Utils.addErrorMessage(fnfe.getMessage(), fnfe); } this.content = this.getAvmService().getContentReader(-1, this.createdPath).getContentString(); - this.fileName = this.formInstanceData.getName(); this.mimeType = MimetypeMap.MIMETYPE_XML; // calculate which locks are present at init time - this.locksPresentAtInit = new ArrayList(4); + this.existingLocks = new HashSet(4); AVMLock lock = this.getAvmLockingService().getLock(AVMUtil.getStoreId(this.createdPath), AVMUtil.getStoreRelativePath(this.createdPath)); if (lock != null) { - this.locksPresentAtInit.add(this.createdPath); + this.existingLocks.add(this.createdPath); if (logger.isDebugEnabled()) logger.debug("Lock exists for xml instance " + this.createdPath + " at initialisation"); @@ -101,7 +104,7 @@ public class EditWebContentWizard extends CreateWebContentWizard AVMUtil.getStoreRelativePath(path)); if (lock != null) { - this.locksPresentAtInit.add(path); + this.existingLocks.add(path); if (logger.isDebugEnabled()) logger.debug("Lock exists for rendition " + path + " at initialisation"); @@ -114,9 +117,9 @@ public class EditWebContentWizard extends CreateWebContentWizard { if (this.formInstanceData != null && this.renditions != null) { - if (this.locksPresentAtInit.contains(this.createdPath) == false) + if (this.existingLocks.contains(this.createdPath) == false) { - // there wasn't a lock on the form at the start of the + // there wasn't an existing lock on the form at the start of the // wizard so remove the one present now if (logger.isDebugEnabled()) logger.debug("removing form instance data lock from " + @@ -126,12 +129,12 @@ public class EditWebContentWizard extends CreateWebContentWizard this.getAvmLockingService().removeLock(AVMUtil.getStoreId(this.createdPath), AVMUtil.getStoreRelativePath(this.createdPath)); } - + for (Rendition r : this.renditions) { String path = r.getPath(); - if (this.locksPresentAtInit.contains(path) == false) + if (this.existingLocks.contains(path) == false) { // there wasn't a lock on the rendition at the start of // the wizard so remove the one present now @@ -139,7 +142,7 @@ public class EditWebContentWizard extends CreateWebContentWizard logger.debug("removing lock from rendition " + AVMUtil.getCorrespondingPathInMainStore(path) + " as user chose to cancel and it wasn't present at initialisation"); - + this.getAvmLockingService().removeLock(AVMUtil.getStoreId(path), AVMUtil.getStoreRelativePath(path)); } @@ -222,8 +225,13 @@ public class EditWebContentWizard extends CreateWebContentWizard // if the renditions were locked before the regenerate, move the lock back to main store String path = rr.getPath(); - if (this.locksPresentAtInit.contains(path)) + if (rr.getExistingLock() != null) { + this.existingLocks.add(path); + } + + if (this.existingLocks.contains(path)) + { if (logger.isDebugEnabled()) logger.debug("transferring existing lock for " + path + " back to " + AVMUtil.getCorrespondingMainStoreName(AVMUtil.getStoreName(path))); @@ -241,14 +249,21 @@ public class EditWebContentWizard extends CreateWebContentWizard final Rendition r = rr.getRendition(); this.renditions.add(r); + String path = r.getPath(); + + if (rr.getExistingLock() != null) + { + this.existingLocks.add(path); + } + if (logger.isDebugEnabled()) - logger.debug("transferring lock for " + r.getPath() + - " back to " + AVMUtil.getCorrespondingMainStoreName(AVMUtil.getStoreName(r.getPath()))); + logger.debug("transferring lock for " + path + + " back to " + AVMUtil.getCorrespondingMainStoreName(AVMUtil.getStoreName(path))); - this.getAvmLockingService().modifyLock(AVMUtil.getStoreId(r.getPath()), - AVMUtil.getStoreRelativePath(r.getPath()), + this.getAvmLockingService().modifyLock(AVMUtil.getStoreId(path), + AVMUtil.getStoreRelativePath(path), null, - AVMUtil.getCorrespondingMainStoreName(AVMUtil.getStoreName(r.getPath())), + AVMUtil.getCorrespondingMainStoreName(AVMUtil.getStoreName(path)), null, null); } diff --git a/source/java/org/alfresco/web/bean/wcm/PromptForWebFormDialog.java b/source/java/org/alfresco/web/bean/wcm/PromptForWebFormDialog.java index c3a9dd24b4..67288b6167 100644 --- a/source/java/org/alfresco/web/bean/wcm/PromptForWebFormDialog.java +++ b/source/java/org/alfresco/web/bean/wcm/PromptForWebFormDialog.java @@ -144,9 +144,11 @@ public class PromptForWebFormDialog extends BaseDialogBean WCMAppModel.ASPECT_FORM_INSTANCE_DATA)) { // build a status message if this is an error case - final FormInstanceData fid = this.getFormsService().getFormInstanceData(this.getAvmNode().getVersion(), avmPath); + + FormInstanceData fid = null; try { + fid = this.getFormsService().getFormInstanceData(this.getAvmNode().getVersion(), avmPath); final Form f = fid.getForm(); this.formName = f.getName(); @@ -162,14 +164,19 @@ public class PromptForWebFormDialog extends BaseDialogBean ? "prompt_for_web_form_form_not_found_error_in_web_project" : "prompt_for_web_form_form_not_found_error"); msg = Application.getMessage(FacesContext.getCurrentInstance(), msg); - msg = (fnfe.getWebProject() != null - ? MessageFormat.format(msg, - fnfe.getFormName(), - fid.getName(), - fnfe.getWebProject().getName()) - : MessageFormat.format(msg, - fnfe.getFormName(), - fid.getName())); + + if (fid != null) + { + msg = (fnfe.getWebProject() != null + ? MessageFormat.format(msg, + fnfe.getFormName(), + fid.getName(), + fnfe.getWebProject().getName()) + : MessageFormat.format(msg, + fnfe.getFormName(), + fid.getName())); + } + this.avmBrowseBean.displayStatusMessage(FacesContext.getCurrentInstance(), msg); } } diff --git a/source/java/org/alfresco/web/bean/wcm/RegenerateRenditionsWizard.java b/source/java/org/alfresco/web/bean/wcm/RegenerateRenditionsWizard.java index a94defbbc8..1550d51d9e 100644 --- a/source/java/org/alfresco/web/bean/wcm/RegenerateRenditionsWizard.java +++ b/source/java/org/alfresco/web/bean/wcm/RegenerateRenditionsWizard.java @@ -525,7 +525,16 @@ public class RegenerateRenditionsWizard { final String avmPath = AVMNodeConverter.ToAVMVersionPath(row.getNodeRef()).getSecond(); final String previewAvmPath = AVMUtil.getCorrespondingPathInPreviewStore(avmPath); - result.add(getFormsService().getFormInstanceData(-1, previewAvmPath)); + + try + { + FormInstanceData fid = getFormsService().getFormInstanceData(-1, previewAvmPath); + result.add(fid); + } + catch (final FormNotFoundException fnfe) + { + // ignore + } } return result; @@ -661,9 +670,10 @@ public class RegenerateRenditionsWizard if (this.regenerateScope.equals(REGENERATE_SCOPE_ALL) || this.regenerateScope.equals(REGENERATE_SCOPE_FORM)) { - final FormInstanceData fid = this.formsService.getFormInstanceData(-1, previewAvmPath); + FormInstanceData fid = null; try { + fid = this.formsService.getFormInstanceData(-1, previewAvmPath); final List regenResults = fid.regenerateRenditions(); for (final FormInstanceData.RegenerateResult rr : regenResults) { @@ -687,7 +697,7 @@ public class RegenerateRenditionsWizard } catch (FormNotFoundException fnfe) { - logger.warn("regenerating renditions of " + fid.getPath() + ": " + fnfe.getMessage(), fnfe); + logger.warn("regenerating renditions of " + previewAvmPath + ": " + fnfe.getMessage(), fnfe); } } else diff --git a/source/java/org/alfresco/web/bean/wcm/SubmitDialog.java b/source/java/org/alfresco/web/bean/wcm/SubmitDialog.java index 640141c73d..f0872bd8f2 100644 --- a/source/java/org/alfresco/web/bean/wcm/SubmitDialog.java +++ b/source/java/org/alfresco/web/bean/wcm/SubmitDialog.java @@ -59,7 +59,9 @@ import org.alfresco.web.app.servlet.FacesHelper; import org.alfresco.web.bean.BrowseBean; import org.alfresco.web.bean.dialog.BaseDialogBean; import org.alfresco.web.bean.repository.Repository; +import org.alfresco.web.forms.Form; import org.alfresco.web.forms.FormInstanceData; +import org.alfresco.web.forms.FormNotFoundException; import org.alfresco.web.forms.FormsService; import org.alfresco.web.forms.Rendition; import org.alfresco.web.ui.common.Utils; @@ -724,7 +726,7 @@ public class SubmitDialog extends BaseDialogBean for (AVMNodeDescriptor node : selected) { - if (AVMWorkflowUtil.isInActiveWorkflow(this.avmBrowseBean.getStagingStore(), node)) + if (AVMWorkflowUtil.isInActiveWorkflow(AVMUtil.getStoreName(node.getPath()), node)) { this.warningItems.add(new ItemWrapper(node)); continue; @@ -750,42 +752,61 @@ public class SubmitDialog extends BaseDialogBean // item is a form (note: could be deleted) or a rendition FormInstanceData fid = null; - if (isRendition) + try { - // found a generated rendition asset - locate the parent form instance data file - // and use this to find all generated assets that are appropriate - // NOTE: this path value is store relative - fid = getFormsService().getRendition(ref).getPrimaryFormInstanceData(true); + if (isRendition) + { + // found a generated rendition asset - locate the parent form instance data file + // and use this to find all generated assets that are appropriate + // NOTE: this path value is store relative + fid = getFormsService().getRendition(ref).getPrimaryFormInstanceData(true); + } + else + { + fid = getFormsService().getFormInstanceData(ref); + } } - else + catch (FormNotFoundException fnfe) { - fid = getFormsService().getFormInstanceData(ref); + logger.warn(fnfe); } - // add the form instance data file to the list for submission - if (!submittedPaths.contains(fid.getPath())) + if (fid != null) { - this.submitItems.add(new ItemWrapper(getAvmService().lookup(-1, fid.getPath(), true))); - submittedPaths.add(fid.getPath()); - } - - // locate renditions for this form instance data file and add to list for submission - for (final Rendition rendition : fid.getRenditions(true)) - { - final String renditionPath = rendition.getPath(); - if (!submittedPaths.contains(renditionPath)) - { - this.submitItems.add(new ItemWrapper(getAvmService().lookup(-1, renditionPath, true))); - submittedPaths.add(renditionPath); - } - } - - // lookup the workflow defaults for that form and store into the list of available workflows - WorkflowDefinition defaultWfDef = fid.getForm().getDefaultWorkflow(); - if (defaultWfDef != null) - { - this.workflows.add(new FormWorkflowWrapper(defaultWfDef.getName(), - fid.getForm().getDefaultWorkflowParameters())); + // add the form instance data file to the list for submission + if (!submittedPaths.contains(fid.getPath())) + { + this.submitItems.add(new ItemWrapper(getAvmService().lookup(-1, fid.getPath(), true))); + submittedPaths.add(fid.getPath()); + } + + // locate renditions for this form instance data file and add to list for submission + for (final Rendition rendition : fid.getRenditions(true)) + { + final String renditionPath = rendition.getPath(); + if (!submittedPaths.contains(renditionPath)) + { + this.submitItems.add(new ItemWrapper(getAvmService().lookup(-1, renditionPath, true))); + submittedPaths.add(renditionPath); + } + } + + // lookup the workflow defaults for that form and store into the list of available workflows + Form f = null; + try + { + f = fid.getForm(); + WorkflowDefinition defaultWfDef = f.getDefaultWorkflow(); + if (defaultWfDef != null) + { + this.workflows.add(new FormWorkflowWrapper(defaultWfDef.getName(), + fid.getForm().getDefaultWorkflowParameters())); + } + } + catch (FormNotFoundException fnfe) + { + logger.warn(fnfe); + } } // See WCM-1090 ACT-1551 diff --git a/source/java/org/alfresco/web/forms/FormInstanceData.java b/source/java/org/alfresco/web/forms/FormInstanceData.java index 935fcb369a..f862731c4d 100644 --- a/source/java/org/alfresco/web/forms/FormInstanceData.java +++ b/source/java/org/alfresco/web/forms/FormInstanceData.java @@ -22,6 +22,7 @@ import java.io.IOException; import java.io.Serializable; import java.util.List; +import org.alfresco.service.cmr.avm.locking.AVMLock; import org.w3c.dom.Document; import org.xml.sax.SAXException; @@ -45,25 +46,30 @@ public interface FormInstanceData private final String path; private final Rendition r; private final Exception e; + private final AVMLock lock; // existing lock otherwise null public RegenerateResult(final RenderingEngineTemplate ret, - final String path, - final Rendition r) + final String path, + final Rendition r, + final AVMLock lock) { this.ret = ret; this.r = r; this.e = null; this.path = path; + this.lock = lock; } - + public RegenerateResult(final RenderingEngineTemplate ret, final String path, - final Exception e) + final Exception e, + final AVMLock lock) { this.ret = ret; this.e = e; this.r = null; this.path = path; + this.lock = lock; } public RenderingEngineTemplate getRenderingEngineTemplate() @@ -85,6 +91,11 @@ public interface FormInstanceData { return this.e; } + + public AVMLock getExistingLock() + { + return this.lock; + } } ///////////////////////////////////////////////////////////////////////////// diff --git a/source/java/org/alfresco/web/forms/FormInstanceDataImpl.java b/source/java/org/alfresco/web/forms/FormInstanceDataImpl.java index fd2b6bdd89..99b1ac5621 100644 --- a/source/java/org/alfresco/web/forms/FormInstanceDataImpl.java +++ b/source/java/org/alfresco/web/forms/FormInstanceDataImpl.java @@ -40,9 +40,11 @@ import org.alfresco.service.cmr.avm.locking.AVMLockingService; import org.alfresco.service.cmr.dictionary.DataTypeDefinition; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.StoreRef; +import org.alfresco.web.app.Application; import org.alfresco.web.app.servlet.FacesHelper; import org.alfresco.web.bean.repository.Repository; import org.alfresco.web.bean.wcm.AVMUtil; +import org.alfresco.web.bean.wcm.WebProject; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.w3c.dom.Document; @@ -60,11 +62,22 @@ import org.xml.sax.SAXException; private static final Log logger = LogFactory.getLog(RenditionImpl.class); private final NodeRef nodeRef; + private final WebProject webProject; + private transient FormsService formsService; /* package */ FormInstanceDataImpl(final NodeRef nodeRef, final FormsService formsService) { + this(nodeRef, formsService, null); + } + + /* package */ FormInstanceDataImpl(final NodeRef nodeRef, + final FormsService formsService, + final WebProject webProject) + { + this.webProject = webProject; + if (nodeRef == null) { throw new NullPointerException(); @@ -152,6 +165,10 @@ import org.xml.sax.SAXException; } catch (FormNotFoundException fnfe) { + if (webProject != null) + { + throw new FormNotFoundException(parentFormName, webProject, this); + } throw new FormNotFoundException(parentFormName, this); } } @@ -189,7 +206,6 @@ import org.xml.sax.SAXException; new HashSet(this.getForm().getRenderingEngineTemplates()); final List result = new LinkedList(); // regenerate existing renditions - boolean renditionLockedBefore = false; String path = null; for (final Rendition r : this.getRenditions()) @@ -207,13 +223,15 @@ import org.xml.sax.SAXException; continue; } } - } + final RenderingEngineTemplate ret = r.getRenderingEngineTemplate(); if (ret == null || !allRets.contains(ret)) { continue; } + + AVMLock lock = null; try { if (logger.isDebugEnabled()) @@ -221,13 +239,10 @@ import org.xml.sax.SAXException; logger.debug("regenerating rendition " + r + " using template " + ret); } - renditionLockedBefore = false; path = r.getPath(); - AVMLock lock = avmLockService.getLock(AVMUtil.getStoreId(path), AVMUtil.getStoreRelativePath(path)); + lock = avmLockService.getLock(AVMUtil.getStoreId(path), AVMUtil.getStoreRelativePath(path)); if (lock != null) { - renditionLockedBefore = true; - if (logger.isDebugEnabled()) { logger.debug("Lock already exists for " + path); @@ -236,14 +251,14 @@ import org.xml.sax.SAXException; ret.render(this, r); allRets.remove(ret); - result.add(new RegenerateResult(ret, path, r)); + result.add(new RegenerateResult(ret, path, r, lock)); } catch (Exception e) { - result.add(new RegenerateResult(ret, path, e)); + result.add(new RegenerateResult(ret, path, e, lock)); // remove lock if there wasn't one before - if (renditionLockedBefore == false) + if (lock == null) { avmLockService.removeLock(AVMUtil.getStoreId(path), AVMUtil.getStoreRelativePath(path)); @@ -255,47 +270,84 @@ import org.xml.sax.SAXException; } } + // get current username for lock checks + String username = Application.getCurrentUser(FacesContext.getCurrentInstance()).getUserName(); + // render all renditions for newly added templates for (final RenderingEngineTemplate ret : allRets) { + AVMLock lock = null; + boolean lockModified = false; + try { - renditionLockedBefore = false; - path = ret.getOutputPathForRendition(this, originalParentAvmPath, getName()); - + path = ret.getOutputPathForRendition(this, originalParentAvmPath, getName().replaceAll("(.+)\\..*", "$1")); + if (logger.isDebugEnabled()) { logger.debug("regenerating rendition of " + this.getPath() + " at " + path + " using template " + ret); } - AVMLock lock = avmLockService.getLock(AVMUtil.getStoreId(path), AVMUtil.getStoreRelativePath(path)); + String storeId = AVMUtil.getStoreId(path); + String storePath = AVMUtil.getStoreRelativePath(path); + String storeName = AVMUtil.getStoreName(path); + + lock = avmLockService.getLock(storeId, storePath); + if (lock != null) { - renditionLockedBefore = true; - if (logger.isDebugEnabled()) { logger.debug("Lock already exists for " + path); } + + if (lock.getStore().equals(storeName) == false) + { + if (lock.getOwners().contains(username)) + { + lockModified = true; + + // lock already exists on path, check it's owned by the current user + if (logger.isDebugEnabled()) + { + logger.debug("transferring lock from " + lock.getStore() + " to " + storeName + " for path: " + path); + } + + avmLockService.modifyLock(storeId, storePath, null, storeName, null, null); + } + } } - result.add(new RegenerateResult(ret, path, ret.render(this, path))); + result.add(new RegenerateResult(ret, path, ret.render(this, path), lock)); } catch (Exception e) { - result.add(new RegenerateResult(ret, path, e)); + result.add(new RegenerateResult(ret, path, e, lock)); - // remove lock if there wasn't one before - if (renditionLockedBefore == false) + String storeId = AVMUtil.getStoreId(path); + String storePath = AVMUtil.getStoreRelativePath(path); + String storeName = AVMUtil.getStoreName(path); + + if (lock == null) { - avmLockService.removeLock(AVMUtil.getStoreId(path), AVMUtil.getStoreRelativePath(path)); + // remove lock if there wasn't one before + avmLockService.removeLock(storeId, storePath); if (logger.isDebugEnabled()) { logger.debug("Removed lock for " + path + " as it failed to generate"); } } + else if (lockModified) + { + if (logger.isDebugEnabled()) + { + logger.debug("transferring lock from " + storeName + " to " + lock.getStore() + " for path: " + path); + } + + avmLockService.modifyLock(storeId, storePath, null, lock.getStore(), null, null); + } } } return result; diff --git a/source/java/org/alfresco/web/forms/FormsService.java b/source/java/org/alfresco/web/forms/FormsService.java index a9850d1b93..bdf54752f3 100644 --- a/source/java/org/alfresco/web/forms/FormsService.java +++ b/source/java/org/alfresco/web/forms/FormsService.java @@ -30,6 +30,7 @@ import org.alfresco.repo.avm.AVMNodeConverter; import org.alfresco.repo.policy.Behaviour; import org.alfresco.repo.policy.JavaBehaviour; import org.alfresco.repo.policy.PolicyComponent; +import org.alfresco.service.cmr.avm.AVMService; import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.ContentService; import org.alfresco.service.cmr.repository.NodeRef; @@ -290,32 +291,27 @@ public final class FormsService return result; } - public FormInstanceData getFormInstanceData(final int version, final String avmPath) + public FormInstanceData getFormInstanceData(final int version, final String avmPath) throws FormNotFoundException { return this.getFormInstanceData(AVMNodeConverter.ToNodeRef(version, avmPath)); } - public FormInstanceData getFormInstanceData(final NodeRef nodeRef) + public FormInstanceData getFormInstanceData(final NodeRef nodeRef) throws FormNotFoundException { final String avmPath = AVMNodeConverter.ToAVMVersionPath(nodeRef).getSecond(); final WebProject webProject = new WebProject(avmPath); - return new FormInstanceDataImpl(nodeRef, this) + + FormInstanceData fid = null; + try { - @Override - public Form getForm() - throws FormNotFoundException - { - final Form f = super.getForm(); - try - { - return webProject.getForm(f.getName()); - } - catch (FormNotFoundException fnfne) - { - throw new FormNotFoundException(f, webProject, this); - } - } - }; + fid = new FormInstanceDataImpl(nodeRef, this, webProject); + return fid; + } + catch (IllegalArgumentException iae) + { + // note: FormNotFoundException extends FileNotFoundException + throw new FormNotFoundException(iae.getMessage()); + } } public Rendition getRendition(final int version, final String avmPath) diff --git a/source/java/org/alfresco/web/forms/xforms/Schema2XForms.java b/source/java/org/alfresco/web/forms/xforms/Schema2XForms.java index 3056a7326e..0d2e46eb88 100644 --- a/source/java/org/alfresco/web/forms/xforms/Schema2XForms.java +++ b/source/java/org/alfresco/web/forms/xforms/Schema2XForms.java @@ -36,8 +36,11 @@ import java.util.TreeMap; import java.util.TreeSet; import java.util.regex.Pattern; +import javax.faces.context.FacesContext; + import org.alfresco.service.namespace.NamespaceService; import org.alfresco.util.Pair; +import org.alfresco.web.app.Application; import org.alfresco.web.forms.XMLUtil; import org.apache.commons.jxpath.JXPathContext; import org.apache.commons.jxpath.Pointer; @@ -1930,7 +1933,7 @@ public class Schema2XForms implements Serializable // add xforms:repeat section if this element re-occurs if ((o.isOptional() && (controlType instanceof XSSimpleTypeDefinition || "anyType".equals(controlType.getName()))) || - (o.maximum == 1 && o.minimum == 1)) + (o.maximum == 1 && o.minimum == 1) || (controlType instanceof XSComplexTypeDefinition && pathToRoot.equals(""))) { return formSection; } @@ -2804,6 +2807,9 @@ public class Schema2XForms implements Serializable final Map enumValues = new LinkedHashMap(enumFacets.getLength()); + + final String nullValue = Application.getMessage(FacesContext.getCurrentInstance(), "please_select"); + enumValues.put(nullValue, null); for (int i = 0; i < enumFacets.getLength(); i++) { enumValues.put(enumFacets.item(i), @@ -2824,29 +2830,6 @@ public class Schema2XForms implements Serializable NamespaceConstants.XFORMS_PREFIX + ":appearance", appearance); - // add the "Please select..." instruction item for the combobox - // and set the isValid attribute on the bind element to check for the "Please select..." - // item to indicate that is not a valid value - final String pleaseSelect = "[Select1 " + caption + "]"; - final Element item = this.createXFormsItem(xformsDocument, pleaseSelect, pleaseSelect); - choices.appendChild(item); - - // not(purchaseOrder/state = '[Choose State]') - //String isValidExpr = "not(" + bindElement.getAttributeNS(NamespaceConstants.XFORMS_NS,"nodeset") + " = '" + pleaseSelect + "')"; - // ->no, not(. = '[Choose State]') - final String isValidExpr = "not( . = '" + pleaseSelect + "')"; - - //check if there was a constraint - String constraint = bindElement.getAttributeNS(NamespaceConstants.XFORMS_NS, "constraint"); - - constraint = (constraint != null && constraint.length() != 0 - ? constraint + " and " + isValidExpr - : isValidExpr); - - bindElement.setAttributeNS(NamespaceConstants.XFORMS_NS, - NamespaceConstants.XFORMS_PREFIX + ":constraint", - constraint); - control.appendChild(choices); this.addChoicesForSelectControl(xformsDocument, choices, enumValues, resourceBundle); return control; @@ -3026,7 +3009,12 @@ public class Schema2XForms implements Serializable for (int i = 0; lexicalPatterns != null && i < lexicalPatterns.getLength() && !SchemaSymbols.ATTVAL_INTEGER.equals(typeName); i++) { - constraints.add("chiba:match(., '" + lexicalPatterns.item(i) + "',null)"); + String pattern = lexicalPatterns.item(i); + if (o.isOptional()) + { + pattern= "(" + pattern + ")?"; + } + constraints.add("chiba:match(., '" + pattern + "',null)"); } } diff --git a/source/java/org/alfresco/web/ui/repo/tag/PageTag.java b/source/java/org/alfresco/web/ui/repo/tag/PageTag.java index 7c1be5423f..6625b4e2c6 100644 --- a/source/java/org/alfresco/web/ui/repo/tag/PageTag.java +++ b/source/java/org/alfresco/web/ui/repo/tag/PageTag.java @@ -211,7 +211,9 @@ public class PageTag extends TagSupport out.write("\n"); } - out.write(""); + out.write("<html><head>"); + out.write("<meta http-equiv=\"X-UA-Compatible\" content=\"IE=EmulateIE7\" />\n"); + out.write("<title>"); if (this.titleId != null && this.titleId.length() != 0) { out.write(Utils.encode(Application.getMessage(pageContext.getSession(), this.titleId))); @@ -228,7 +230,6 @@ public class PageTag extends TagSupport out.write("<link rel=\"search\" type=\"application/opensearchdescription+xml\" href=\"" + reqPath + "/wcservice/api/search/keyword/description.xml\" title=\"Alfresco Keyword Search\">\n"); out.write("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n"); - out.write("<meta http-equiv=\"X-UA-Compatible\" content=\"Edge\" />\n"); } // CSS style includes diff --git a/source/web/WEB-INF/faces-config-beans.xml b/source/web/WEB-INF/faces-config-beans.xml index 396f888143..12ae1c2b61 100644 --- a/source/web/WEB-INF/faces-config-beans.xml +++ b/source/web/WEB-INF/faces-config-beans.xml @@ -645,6 +645,10 @@ <property-name>contentUsageService</property-name> <value>#{ContentUsageService}</value> </managed-property> + <managed-property> + <property-name>userRegistrySynchronizer</property-name> + <value>#{userRegistrySynchronizer}</value> + </managed-property> </managed-bean> <managed-bean> diff --git a/source/web/jsp/users/edit-user-details.jsp b/source/web/jsp/users/edit-user-details.jsp index 3ade1b70e1..b217679963 100644 --- a/source/web/jsp/users/edit-user-details.jsp +++ b/source/web/jsp/users/edit-user-details.jsp @@ -57,31 +57,31 @@ function updateButtonState() <h:panelGrid columns="3" cellpadding="2" cellspacing="2" width="100%" columnClasses=",alignTop,"> <h:graphicImage value="/images/icons/required_field.gif" alt="#{msg.required_field}" /> <h:outputText value="#{msg.first_name}:"/> - <h:inputText id="first-name" value="#{DialogManager.bean.firstName}" size="35" maxlength="1024" onkeyup="updateButtonState();" onchange="updateButtonState();" /> + <h:inputText id="first-name" value="#{DialogManager.bean.firstName}" disabled="#{UsersBeanProperties.immutability.firstName}" size="35" maxlength="1024" onkeyup="updateButtonState();" onchange="updateButtonState();" /> <h:graphicImage value="/images/icons/required_field.gif" alt="#{msg.required_field}" /> <h:outputText value="#{msg.last_name}:"/> - <h:inputText id="last-name" value="#{DialogManager.bean.lastName}" size="35" maxlength="1024" onkeyup="updateButtonState();" onchange="updateButtonState();" /> + <h:inputText id="last-name" value="#{DialogManager.bean.lastName}" disabled="#{UsersBeanProperties.immutability.lastName}" size="35" maxlength="1024" onkeyup="updateButtonState();" onchange="updateButtonState();" /> <h:graphicImage value="/images/icons/required_field.gif" alt="#{msg.required_field}" /> <h:outputText value="#{msg.email}"/> - <h:inputText id="email" value="#{DialogManager.bean.email}" size="35" maxlength="1024" onkeyup="updateButtonState();" onchange="updateButtonState();" /> + <h:inputText id="email" value="#{DialogManager.bean.email}" disabled="#{UsersBeanProperties.immutability.email}" size="35" maxlength="1024" onkeyup="updateButtonState();" onchange="updateButtonState();" /> <f:verbatim/> <h:outputText value="#{msg.user_organization}:"/> - <h:inputText id="organisation" value="#{DialogManager.bean.personProperties.organization}" size="35" maxlength="1024" /> + <h:inputText id="organisation" value="#{DialogManager.bean.personProperties.organization}" disabled="#{UsersBeanProperties.immutability.organization}" size="35" maxlength="1024" /> <f:verbatim/> <h:outputText value="#{msg.user_jobtitle}:"/> - <h:inputText id="jobtitle" value="#{DialogManager.bean.personProperties.jobtitle}" size="35" maxlength="1024" /> + <h:inputText id="jobtitle" value="#{DialogManager.bean.personProperties.jobtitle}" disabled="#{UsersBeanProperties.immutability.jobtitle}" size="35" maxlength="1024" /> <f:verbatim/> <h:outputText value="#{msg.user_location}:"/> - <h:inputText id="location" value="#{DialogManager.bean.personProperties.location}" size="35" maxlength="1024" /> + <h:inputText id="location" value="#{DialogManager.bean.personProperties.location}" disabled="#{UsersBeanProperties.immutability.location}" size="35" maxlength="1024" /> <f:verbatim/> <h:outputText value="#{msg.presence_provider}:"/> - <h:selectOneMenu value="#{DialogManager.bean.personProperties.presenceProvider}"> + <h:selectOneMenu value="#{DialogManager.bean.personProperties.presenceProvider}" disabled="#{UsersBeanProperties.immutability.presenceProvider}"> <f:selectItem itemValue="" itemLabel="(#{msg.none})"/> <f:selectItem itemValue="skype" itemLabel="Skype"/> <f:selectItem itemValue="yahoo" itemLabel="Yahoo"/> @@ -89,11 +89,11 @@ function updateButtonState() <f:verbatim/> <h:outputText value="#{msg.presence_username}:"/> - <h:inputText value="#{DialogManager.bean.personProperties.presenceUsername}" size="35" maxlength="256" /> + <h:inputText value="#{DialogManager.bean.personProperties.presenceUsername}" disabled="#{UsersBeanProperties.immutability.presenceUsername}" size="35" maxlength="256" /> <f:verbatim/> <h:outputText value="#{msg.user_description}:"/> - <h:inputTextarea id="biography" value="#{DialogManager.bean.personDescription}" rows="6" cols="60" /> + <h:inputTextarea id="biography" value="#{DialogManager.bean.personDescription}" disabled="#{UsersBeanProperties.immutability.personDescription}" rows="6" cols="60" /> <f:verbatim/> <h:outputText value="#{msg.user_avatar}:"/> diff --git a/source/web/jsp/users/new-user-wizard/person-properties.jsp b/source/web/jsp/users/new-user-wizard/person-properties.jsp index b286926c8c..a644692759 100644 --- a/source/web/jsp/users/new-user-wizard/person-properties.jsp +++ b/source/web/jsp/users/new-user-wizard/person-properties.jsp @@ -53,15 +53,15 @@ <h:panelGrid columns="3" cellpadding="2" cellspacing="2" width="100%"> <h:graphicImage value="/images/icons/required_field.gif" alt="#{msg.required_field}" /> <h:outputText value="#{msg.first_name}:"/> - <h:inputText id="firstName" value="#{WizardManager.bean.firstName}" size="35" maxlength="1024" onkeyup="updateButtonState();" onchange="updateButtonState();" /> + <h:inputText id="firstName" value="#{WizardManager.bean.firstName}" disabled="#{WizardManager.bean.personPropertiesImmutability.firstName}" size="35" maxlength="1024" onkeyup="updateButtonState();" onchange="updateButtonState();" /> <h:graphicImage value="/images/icons/required_field.gif" alt="#{msg.required_field}" /> <h:outputText value="#{msg.last_name}:"/> - <h:inputText id="lastName" value="#{WizardManager.bean.lastName}" size="35" maxlength="1024" onkeyup="updateButtonState();" onchange="updateButtonState();" /> + <h:inputText id="lastName" value="#{WizardManager.bean.lastName}" disabled="#{WizardManager.bean.personPropertiesImmutability.lastName}" size="35" maxlength="1024" onkeyup="updateButtonState();" onchange="updateButtonState();" /> <h:graphicImage value="/images/icons/required_field.gif" alt="#{msg.required_field}" /> <h:outputText value="#{msg.email}"/> - <h:inputText id="email" value="#{WizardManager.bean.email}" size="35" maxlength="1024" onkeyup="updateButtonState();" onchange="updateButtonState();" /> + <h:inputText id="email" value="#{WizardManager.bean.email}" disabled="#{WizardManager.bean.personPropertiesImmutability.email}" size="35" maxlength="1024" onkeyup="updateButtonState();" onchange="updateButtonState();" /> </h:panelGrid> <h:panelGrid columns="1" cellpadding="2" style="padding-top: 4px; padding-bottom: 4px;" @@ -74,23 +74,23 @@ <h:inputText value="#{WizardManager.bean.companyId}" size="35" maxlength="1024" /> <h:outputText value="#{msg.user_organization}:"/> - <h:inputText id="organisation" value="#{WizardManager.bean.organization}" size="35" maxlength="1024" /> + <h:inputText id="organisation" value="#{WizardManager.bean.organization}" disabled="#{WizardManager.bean.personPropertiesImmutability.organization}" size="35" maxlength="1024" /> <h:outputText value="#{msg.user_jobtitle}:"/> - <h:inputText id="jobtitle" value="#{WizardManager.bean.jobtitle}" size="35" maxlength="1024" /> + <h:inputText id="jobtitle" value="#{WizardManager.bean.jobtitle}" disabled="#{WizardManager.bean.personPropertiesImmutability.jobtitle}" size="35" maxlength="1024" /> <h:outputText value="#{msg.user_location}:"/> - <h:inputText id="location" value="#{WizardManager.bean.location}" size="35" maxlength="1024" /> + <h:inputText id="location" value="#{WizardManager.bean.location}" disabled="#{WizardManager.bean.personPropertiesImmutability.location}" size="35" maxlength="1024" /> - <h:outputText value="#{msg.presence_provider}:"/> - <h:selectOneMenu value="#{WizardManager.bean.presenceProvider}"> + <h:outputText value="#{msg.presence_provider}:" /> + <h:selectOneMenu value="#{WizardManager.bean.presenceProvider}" disabled="#{WizardManager.bean.personPropertiesImmutability.presenceProvider}"> <f:selectItem itemValue="" itemLabel="(#{msg.none})"/> <f:selectItem itemValue="skype" itemLabel="Skype"/> <f:selectItem itemValue="yahoo" itemLabel="Yahoo"/> </h:selectOneMenu> <h:outputText value="#{msg.presence_username}:"/> - <h:inputText value="#{WizardManager.bean.presenceUsername}" size="35" maxlength="256" /> + <h:inputText value="#{WizardManager.bean.presenceUsername}" disabled="#{WizardManager.bean.personPropertiesImmutability.presenceUsername}" size="35" maxlength="256" /> <h:outputText value="#{msg.sizeQuota}:" rendered="#{UsersBeanProperties.usagesEnabled == true}"/> <h:panelGroup> diff --git a/source/web/jsp/users/user-console.jsp b/source/web/jsp/users/user-console.jsp index 16969fdb17..6f27f81ef5 100644 --- a/source/web/jsp/users/user-console.jsp +++ b/source/web/jsp/users/user-console.jsp @@ -95,7 +95,7 @@ <a:actionLink id="change-password" value="#{msg.change_password}" action="dialog:changeMyPassword" image="/images/icons/change_password.gif" - rendered="#{!NavigationBean.isGuest && NavigationBean.allowUserConfig}" /> + rendered="#{!NavigationBean.isGuest && NavigationBean.allowUserConfig && NavigationBean.allowUserChangePassword}" /> </a:panel> </h:panelGroup> diff --git a/source/web/jsp/users/users.jsp b/source/web/jsp/users/users.jsp index c9b4ed7b37..5e45311eb9 100644 --- a/source/web/jsp/users/users.jsp +++ b/source/web/jsp/users/users.jsp @@ -132,7 +132,7 @@ <f:facet name="header"> <h:outputText value="#{msg.actions}" /> </f:facet> - <a:actionLink rendered="#{r.isMutable}" value="#{msg.modify}" image="/images/icons/edituser.gif" showLink="false" action="wizard:editUser" actionListener="#{DialogManager.bean.setupUserAction}"> + <a:actionLink value="#{msg.modify}" image="/images/icons/edituser.gif" showLink="false" action="wizard:editUser" actionListener="#{DialogManager.bean.setupUserAction}"> <f:param name="id" value="#{r.id}" /> </a:actionLink> <a:actionLink rendered="#{r.isMutable}" value="#{msg.change_password}" image="/images/icons/change_password.gif" showLink="false" action="dialog:changePassword" actionListener="#{DialogManager.bean.setupUserAction}"> diff --git a/source/web/scripts/ajax/common.js b/source/web/scripts/ajax/common.js index 78ef33fc56..6ec218da05 100644 --- a/source/web/scripts/ajax/common.js +++ b/source/web/scripts/ajax/common.js @@ -4,6 +4,34 @@ // +function getIEEngine() +{ + var engine = null; + + if (document.documentMode) // IE8 + engine = document.documentMode; + else // IE 5-7 + { + engine = 5; // Assume quirks mode unless proven otherwise + if (document.compatMode) + { + if (document.compatMode == "CSS1Compat") + engine = 7; // standards mode + } + } + return engine; + +} + +function getIEVersion() +{ + var rv = -1; + var ua = window.navigator.userAgent; + var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})"); + if (re.exec(ua) != null) rv = parseFloat(RegExp.$1); + return rv; +} + // Global Alfresco namespace object if (typeof Alfresco == "undefined") { diff --git a/source/web/scripts/ajax/xforms.js b/source/web/scripts/ajax/xforms.js index 21fbd916d9..88f54890a1 100644 --- a/source/web/scripts/ajax/xforms.js +++ b/source/web/scripts/ajax/xforms.js @@ -31,6 +31,9 @@ // Initiliaze dojo requirements, tinymce, and add a hook to load the xform. //////////////////////////////////////////////////////////////////////////////// +alfresco.ieVersion = getIEVersion(); +alfresco.ieEngine = alfresco.ieVersion == -1 ? -1 : getIEEngine(); + djConfig.parseWidgets = false; dojo.require("dojo.lfx.html"); alfresco.log = alfresco.constants.DEBUG ? log : Class.empty; @@ -682,8 +685,8 @@ alfresco.xforms.TextField = alfresco.xforms.Widget.extend({ if (this.isReadonly()) { - this.widget.setAttribute("readonly", this.isReadonly()); - this.widget.setAttribute("disabled", this.isReadonly()); + this.widget.setAttribute("readonly", true); + this.widget.setAttribute("disabled", true); } else { @@ -835,12 +838,13 @@ alfresco.xforms.PlainTextEditor = alfresco.xforms.Widget.extend({ this.widget.appendChild(document.createTextNode(initialValue)); if (this.isReadonly()) { - this.widget.setAttribute("readonly", this.isReadonly()); + this.widget.setAttribute("readonly", true); } var borderWidth = (this.widget.offsetWidth - this.widget.clientWidth); var marginRight = 2; this.widget.style.marginRight = marginRight + "px"; - this.widget.style.width = (((attach_point.offsetWidth - borderWidth - marginRight) / attach_point.offsetWidth) * 100) + "%"; + var ow = attach_point.offsetWidth; + this.widget.style.width = (((ow - borderWidth - marginRight) / ow) * 100) + "%"; this.widget.onchange =this._textarea_changeHandler.bindAsEventListener(this); }, @@ -2782,7 +2786,10 @@ alfresco.xforms.VGroup = alfresco.xforms.AbstractGroup.extend({ child.domContainer); } - var contentDiv = new Element("div", { "id": child.id + "-content", "class": "xformsGroupItem"}); + var contentDiv = new Element("div", { "id": child.id + "-content", "class": "xformsGroupItem", + "styles": {"left": (child instanceof alfresco.xforms.AbstractGroup + ? "0px" + : "30%")}}); this._contentDivs[child.id] = contentDiv; if (!(child instanceof alfresco.xforms.AbstractGroup)) { @@ -2791,36 +2798,40 @@ alfresco.xforms.VGroup = alfresco.xforms.AbstractGroup.extend({ } child.domContainer.appendChild(contentDiv); - contentDiv.style.left = (child instanceof alfresco.xforms.AbstractGroup - ? "0px" - : "30%"); var contentDivWidth = "100%"; // the following does avoid devision by zero ... in contentDiv.offsetLeft / child.domContainer.offsetWidth - if (!(child instanceof alfresco.xforms.AbstractGroup) && child.domContainer.offsetWidth != 0) + var ow = child.domContainer.offsetWidth; + if (!(child instanceof alfresco.xforms.AbstractGroup) && ow != 0) { - contentDivWidth = ((1 - (contentDiv.offsetLeft / child.domContainer.offsetWidth)) * 100) + "%"; + contentDivWidth = ((1 - (contentDiv.offsetLeft / ow)) * 100) + "%"; } contentDiv.style.width = contentDivWidth; child.render(contentDiv); + + var oh = contentDiv.offsetHeight; + var mt = contentDiv.getStyle("margin-top").toInt(); if (!(child instanceof alfresco.xforms.AbstractGroup)) { child.domContainer.style.height = - Math.max(contentDiv.offsetHeight + - contentDiv.getStyle("margin-top").toInt() + + Math.max(oh + + mt + contentDiv.getStyle("margin-bottom").toInt(), 20) + "px"; } - alfresco.log(contentDiv.getAttribute("id") + " offsetTop is " + contentDiv.offsetTop); - contentDiv.style.top = "-" + Math.max(0, contentDiv.offsetTop - contentDiv.getStyle("margin-top").toInt()) + "px"; + var ot = contentDiv.offsetTop; + alfresco.log(contentDiv.getAttribute("id") + " offsetTop is " + ot); + var top = Math.max(0, ot - mt); + contentDiv.style.top = "-" + top + "px"; + if (contentDiv.labelNode) { // contentDiv.labelNode.style.top = (contentDiv.offsetTop + ((.5 * contentDiv.offsetHeight) - // (.5 * contentDiv.labelNode.offsetHeight))) + "px"; contentDiv.labelNode.style.position = "relative"; - contentDiv.labelNode.style.top = contentDiv.offsetTop + "px"; - contentDiv.labelNode.style.height = contentDiv.offsetHeight + "px"; + contentDiv.labelNode.style.top = "0px"; + contentDiv.labelNode.style.height = oh + "px"; contentDiv.labelNode.style.lineHeight = contentDiv.labelNode.style.height; } @@ -2939,18 +2950,19 @@ alfresco.xforms.VGroup = alfresco.xforms.AbstractGroup.extend({ contentDiv.style.position = "static"; contentDiv.style.top = "0px"; - contentDiv.style.left = "0px"; +// contentDiv.style.left = "0px"; contentDiv.style.position = "relative"; contentDiv.style.left = (this._children[i] instanceof alfresco.xforms.AbstractGroup ? "0px" : "30%"); - if (this._children[i].domContainer.parentNode.offsetWidth != 0) + parentOffsetWidth = this._children[i].domContainer.parentNode.offsetWidth; + if (parentOffsetWidth != 0) { contentDiv.style.width = (this._children[i] instanceof alfresco.xforms.AbstractGroup ? "100%" : (1 - (contentDiv.offsetLeft / - this._children[i].domContainer.parentNode.offsetWidth)) * 100 + "%"); + parentOffsetWidth)) * 100 + "%"); } else { @@ -2964,26 +2976,17 @@ alfresco.xforms.VGroup = alfresco.xforms.AbstractGroup.extend({ if (!(this._children[i] instanceof alfresco.xforms.AbstractGroup)) { + var contentDivMarginTop = contentDiv.getStyle("margin-top").toInt(); this._children[i].domContainer.style.height = Math.max(contentDiv.offsetHeight + - contentDiv.getStyle("margin-top").toInt() + + contentDivMarginTop + contentDiv.getStyle("margin-bottom").toInt(), 20) + "px"; } - contentDiv.style.top = "-" + Math.max(0, contentDiv.offsetTop - contentDiv.getStyle("margin-top").toInt()) + "px"; + contentDiv.style.top = "-" + Math.max(0, contentDiv.offsetTop - + (contentDivMarginTop == undefined ? contentDiv.getStyle("margin-top").toInt() : contentDivMarginTop)) + "px"; - var labelNode = contentDiv.labelNode; - if (labelNode) - { -// labelNode.style.position = "static"; -// labelNode.style.top = "0px"; -// labelNode.style.left = "0px"; -// labelNode.style.position = "relative"; - -// labelNode.style.top = (contentDiv.offsetTop + ((.5 * contentDiv.offsetHeight) - -// (.5 * labelNode.offsetHeight))) + "px"; - } } }, @@ -3669,7 +3672,9 @@ alfresco.xforms.Repeat = alfresco.xforms.VGroup.extend({ _updateDisplay: function(recursively) { - this.parent(recursively); + var recurseOnChildren = alfresco.ieVersion != -1 && alfresco.ieEngine < 8; + this.parent(recursively && !recurseOnChildren); + if (this.getViewRoot().focusedRepeat != null && (this.getViewRoot().focusedRepeat == this || this.getViewRoot().focusedRepeat.isAncestorOf(this))) @@ -3699,7 +3704,7 @@ alfresco.xforms.Repeat = alfresco.xforms.VGroup.extend({ this._repeatControls[i].style.backgroundColor = this._children[i].domContainer.getStyle("background-color"); - if (window.navigator.appName == "Microsoft Internet Explorer") + if (recurseOnChildren) { this._children[i]._updateDisplay(true); } @@ -4242,6 +4247,8 @@ alfresco.xforms.XForm = new Class({ { if (xformsNode.childNodes[i].nodeType != document.ELEMENT_NODE) { + if (alfresco.ieVersion == -1) + { // fix for ETWOTWO-490, hide elements after rendering (Mozila/Firefox) if ((i == (xformsNode.childNodes.length - 1)) && (parentWidget instanceof alfresco.xforms.SwitchGroup)) @@ -4254,6 +4261,7 @@ alfresco.xforms.XForm = new Class({ } } } + } continue; } alfresco.log("loading " + xformsNode.childNodes[i].nodeName +