Commits

Joachim Lingner  committed e495521

jl155 #i111592# rewrite dependency solving, step 4

  • Participants
  • Parent commits ca10085

Comments (0)

Files changed (9)

File desktop/source/deployment/gui/dp_gui_updatedata.cxx

 #include "dp_gui_updatedata.hxx"
 #include "dp_gui.hrc"
 #include "dp_gui_shared.hxx"
+#include "dp_identifier.hxx"
+#include "dp_dependencies.hxx"
 
 using namespace ::com::sun::star;
 
 namespace dp_gui {
 
+namespace {
+
+::rtl::OUString getDisplayString(::rtl::OUString const & name,
+                        ::rtl::OUString const & version,
+    bool bBrowserUpdate)
+{
+    rtl::OUStringBuffer b(name);
+    //The extension dialog does not show a string "Version" in front of the version.
+    // b.append(static_cast< sal_Unicode >(' '));
+    // {
+    //     vos::OGuard g( Application::GetSolarMutex() );
+    //     b.append(String(DpGuiResId(RID_STR_UPDATE_VERSION)));
+    // }
+    b.append(static_cast< sal_Unicode >(' '));
+    b.append(version);
+    
+    if (bBrowserUpdate) 
+    {
+        b.append(static_cast< sal_Unicode >(' '));
+        {
+            vos::OGuard g( Application::GetSolarMutex() );
+            b.append(String(DpGuiResId(RID_STR_UPDATE_BROWSERBASED)));
+        }
+    }        
+    return b.makeStringAndClear();
+}
+
+::std::vector<uno::Reference<xml::dom::XElement> >
+getInterExtensionDependencies(dp_misc::DescriptionInfoset const & infoset)
+{
+    uno::Reference< xml::dom::XNodeList > deps(
+        infoset.getDependencies());
+    ::sal_Int32 n = deps->getLength();
+    // css::uno::Sequence< css::uno::Reference< css::xml::dom::XElement > >
+    //     unsatisfied(n);
+    ::sal_Int32 unsat = 0;
+    ::std::vector<uno::Reference<xml::dom::XElement> > vecDeps;
+    for (::sal_Int32 i = 0; i < n; ++i)
+    {
+        css::uno::Reference< css::xml::dom::XElement > e(
+            deps->item(i), css::uno::UNO_QUERY_THROW);
+        if (dp_misc::Dependencies::isInterExtensionDependency(e))
+            vecDeps.push_back(e);
+    }
+    return vecDeps;
+}
+} //end namespace
+
 UpdateData::UpdateData(
     uno::Reference<uno::XComponentContext> const & context,
     uno::Reference< deployment::XPackage > const & aExt, 
     uno::Reference< xml::dom::XNode > const & updateInfo,
     ::std::vector< uno::Reference<xml::dom::XElement> > const & unsatisfiedDeps,
-    ::std::vector< uno::Reference<xml::dom::XElement> > const & requiredExts): 
-    bIsShared(false), aInstalledExtension(aExt), 
-    aUpdateInfo(updateInfo), dependencySolved(false),
+    ::std::vector< uno::Reference<xml::dom::XElement> > const & requiredExts,
+    bool bShared): 
+    bIsShared(bShared), 
+    aUpdateInfo(updateInfo),
     unsatisfiedDependencies(unsatisfiedDeps),
     requiredUpdates(requiredExts)
 {
+    identifier = dp_misc::getIdentifier(aExt);
+    name = aExt->getDisplayName();
     dp_misc::DescriptionInfoset infoset(context, aUpdateInfo);
     OSL_ASSERT(infoset.getVersion().getLength() != 0);
     const ::boost::optional< ::rtl::OUString> updateWebsiteURL(
         sWebsiteURL = *updateWebsiteURL;
     onlineVersion = updateVersion = infoset.getVersion();
 
-    // prepare the display string for the update dialog
-    OSL_ASSERT(aInstalledExtension.is());
-    rtl::OUStringBuffer b(aInstalledExtension->getDisplayName());
-    b.append(static_cast< sal_Unicode >(' '));
-    {
-        vos::OGuard g( Application::GetSolarMutex() );
-        b.append(String(DpGuiResId(RID_STR_UPDATE_VERSION)));
-    }
-    b.append(static_cast< sal_Unicode >(' '));
-    b.append(updateVersion);
-    
-    if (sWebsiteURL.getLength()) 
-    {
-        b.append(static_cast< sal_Unicode >(' '));
-        {
-            vos::OGuard g( Application::GetSolarMutex() );
-            b.append(String(DpGuiResId(RID_STR_UPDATE_BROWSERBASED)));
-        }
-    }        
-    sUpdateDisplayString = b.makeStringAndClear();
+    sUpdateDisplayString = getDisplayString(name, onlineVersion, sWebsiteURL.getLength());
 };
 
 UpdateData::UpdateData(
-    ::rtl::OUString const & /*extensionId*/)
+    uno::Reference<uno::XComponentContext> const & context,
+    ::rtl::OUString const & displayName,
+    uno::Reference<xml::dom::XNode> const & updateInformation,
+    bool bShared):
+    name(displayName), aUpdateInfo(updateInformation), bIsShared(bShared)
 {
-    //ToDo: replace aInstalledExtension
+    dp_misc::DescriptionInfoset info(context, updateInformation);
+    ::boost::optional< ::rtl::OUString > optVersion = info.getIdentifier();
+    if (optVersion)
+        identifier = *optVersion;
+
+    const ::boost::optional< ::rtl::OUString> updateWebsiteURL(
+        info.getLocalizedUpdateWebsiteURL());
+    if (updateWebsiteURL)
+        sWebsiteURL = *updateWebsiteURL;
+
+    onlineVersion = updateVersion = info.getVersion();
+    sUpdateDisplayString = getDisplayString(name, onlineVersion, sWebsiteURL.getLength());
+
+    requiredUpdates = getInterExtensionDependencies(info);
+
 }
+
+
 } //namespace dp_gui
 
 

File desktop/source/deployment/gui/dp_gui_updatedata.hxx

 
 struct UpdateData
 {
+    //Only use this constructor, if all dependencies are satisfied!!!
     UpdateData(
-            ::rtl::OUString const & extensionId);
+        ::com::sun::star::uno::Reference<
+            ::com::sun::star::uno::XComponentContext > const & context,
+        ::rtl::OUString const & displayName,
+        ::com::sun::star::uno::Reference<
+            ::com::sun::star::xml::dom::XNode > const & updateInfo,
+        bool bShared);
     
     UpdateData(
         ::com::sun::star::uno::Reference<
         ::std::vector< ::com::sun::star::uno::Reference<
             ::com::sun::star::xml::dom::XElement> > const & unsatisfiedDependencies,
         ::std::vector< ::com::sun::star::uno::Reference<
-            ::com::sun::star::xml::dom::XElement> > const & requiredExtensions
+     		::com::sun::star::xml::dom::XElement> > const & requiredExtensions,
+		bool bShared
         );
 
+    //The extension identifier
+    ::rtl::OUString identifier;
+
+    //The localized display name
+    ::rtl::OUString name;
+    
     //When entries added to the listbox then there can be one for the user update and one
     //for the shared update. However, both list entries will contain the same UpdateData.
     //isShared is used to indicate which one is used for the shared entry.
+	//If the UpdateData represents an extension which is required by another
+	//update, then it must be installed in the same repository of the
+	//extension which is going to be updated. bIsShared is used to determine this.
     bool bIsShared;
 
-    //The currently installed extension which is going to be updated. If the extension exist in
-    //multiple repositories then it is the one with the highest version.
-    ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > aInstalledExtension;
-
     //The version of the update. This is either the same as onlineVersion or
     //if the update comes from a local repository (bundled, shared) then it
     //is the same as aUpdateSource.getVersion
     ::com::sun::star::uno::Reference< ::com::sun::star::xml::dom::XNode > aUpdateInfo;
     //version of the update
     ::rtl::OUString onlineVersion;
-    //during the download
+
     ::rtl::OUString sLocalURL;
     //The URL of the website wher the download can be obtained.
     ::rtl::OUString sWebsiteURL;
     ::std::vector< ::com::sun::star::uno::Reference<
         ::com::sun::star::xml::dom::XElement > > requiredUpdates;
 
-    //Indicates if UpdateDialog::Thread::solveDependency has already run
-    bool dependencySolved;
-    
     //For local update
     //=====================
     //The locale extension which is used as update for the user or shared repository.
     //If set then the data for the online update (aUpdateInfo, sLocalURL, sWebsiteURL)
     //are to be ignored.
     ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage >
-    aUpdateSource;
-    
-    // ID to find this entry in the update listbox
-    USHORT  m_nID;
-    bool    m_bIgnored;
+    aUpdateSource;    
 };
 }
 

File desktop/source/deployment/gui/dp_gui_updatedialog.cxx

 }
 
 
-bool isInterExtensionDependency(
-    uno::Reference< xml::dom::XElement > const & e)
-{
-    if (e->getNamespaceURI().equalsAsciiL(
-            RTL_CONSTASCII_STRINGPARAM("http://openoffice.org/extensions/description/2006"))
-        && e->getTagName().equalsAsciiL(
-            RTL_CONSTASCII_STRINGPARAM("extension")))
-    {
-        return true;
-    }
-    return false;
-}
-
 //Checks if there are other than inter-extension dependencies
 bool hasOtherDependency(uno::Sequence<uno::Reference<xml::dom::XElement> > const & seqDep)
 {
     for (sal_Int32 i = 0; i < seqDep.getLength(); i++)
     {
-        if (!isInterExtensionDependency(seqDep[i]))
+        if (!dp_misc::Dependencies::isInterExtensionDependency(seqDep[i]))
             return true;
     }
     return false;
 MatchDependingExtension::MatchDependingExtension(
     dp_gui::UpdateData const & data)
 {
-    m_identifier = dp_misc::getIdentifier(data.aInstalledExtension);
+    m_identifier = data.identifier;
     m_version = data.updateVersion;
 }
 
 
 bool MatchRequiredExtension::operator ()( dp_gui::UpdateData const & data ) const
 {
-    if (m_identifier.equals(dp_misc::getIdentifier(data.aInstalledExtension))
+    if (m_identifier.equals(data.identifier)
         && dp_misc::compareVersions(data.updateVersion, m_version) != dp_misc::LESS)
         return true;
      return false;
 
 MatchUpdateData::MatchUpdateData(dp_gui::UpdateData const & data)
 {
-    m_identifier = dp_misc::getIdentifier(data.aInstalledExtension);
+    m_identifier = data.identifier;
 }
 
 MatchUpdateData::MatchUpdateData(rtl::OUString const & identifier):
 
 bool MatchUpdateData::operator () (dp_gui::UpdateData const & addedData)
 {
-    if (dp_misc::getIdentifier(addedData.aInstalledExtension).equals(m_identifier))
+    if (addedData.identifier.equals(m_identifier))
         return true;
     return false;
 }
     virtual ~Thread();
 
     virtual void execute();
-
-//     bool solveDependency(
-//         uno::Reference<xml::dom::XElement> const & dep,
-//         ::std::vector< dp_gui::UpdateData> & vecDisabledAndUpdateData);
-
-        bool solveDependency(
+    typedef ::std::hash_map< ::rtl::OUString,
+                             ::std::pair< ::rtl::OUString, uno::Reference< xml::dom::XNode> >,
+                             ::rtl::OUStringHash>
+                             RequiredUpdatesMap;
+    bool solveDependency(
         uno::Reference<xml::dom::XElement> const  & dependency,
         dp_misc::UpdateInfoMap const & updateInfos,
-        dp_misc::UpdateInfoMap  & inout_requiredUpdates,
+        RequiredUpdatesMap  & inout_requiredUpdates,
         ::std::vector< uno::Reference<xml::dom::XElement> > &
         inout_failedDeps)  const;
 
-    void fixInterExtensionDependencies(
-        ::std::vector< dp_gui::UpdateData> & vecDisabledAndUpdateData);
-
 #if 0
     void handleGeneralError(uno::Any const & exception) const;
 #endif
 
     bool update(dp_gui::UpdateData & data) const;
 
-    ::std::vector<dp_gui::UpdateData>
-    getUpdateData(dp_misc::UpdateInfoMap const & updateInformation) const;
+    ::std::vector<dp_gui::UpdateData> getUpdateData() const;
     
     uno::Reference< uno::XComponentContext > m_context;
+    uno::Reference<deployment::XExtensionManager> m_extensionMgr;
     UpdateDialog & m_dialog;
     std::vector< uno::Reference< deployment::XPackage > > m_vExtensionList;
     uno::Reference< deployment::XUpdateInformationProvider > m_updateInformation;
             if ( m_xInteractionHdl.is() )
                 m_updateInformation->setInteractionHandler( m_xInteractionHdl );
         }
+
+        m_extensionMgr = deployment::ExtensionManager::get(m_context);
     }
 }
 
     updateData(xContext, thePackage,
                uno::Reference<xml::dom::XNode>(),
                ::std::vector<uno::Reference<xml::dom::XElement> >(),
-               ::std::vector<uno::Reference<xml::dom::XElement> >())
+               ::std::vector<uno::Reference<xml::dom::XElement> >(), false)
 {
 }
 
         m_updateInformation->setInteractionHandler( uno::Reference< task::XInteractionHandler > () );
 }
 
-//Todo ring dependencies
-//Only solves the inter-extenions dependencies among the update extensions
-// bool UpdateDialog::Thread::solveDependency(
-//     uno::Reference<xml::dom::XElement> const & dep,
-//     ::std::vector< dp_gui::UpdateData> & vecUpdateData)
-// {
-//     bool ret = false;
-//     //First check if it is a inter-extension dependency
-//     if (dep.is() && ! isInterExtensionDependency(dep))
-//         return false;
-//     const ::rtl::OUString idRequired = dep.is() ? dep->getAttribute(
-//         ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("identifier"))) :
-//         rtl::OUString();
-
-//     const ::rtl::OUString minVersion = dep.is() ? dep->getAttribute(
-//         ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("minimum-version"))) :
-//         rtl::OUString();
-
-//     bool bNoExtensionWithRequiredIdentifier = false;
-//     //find the required extension  among all pontential extension updates
-//     typedef ::std::vector< UpdateData>::iterator CIT;
-//     for (CIT i = vecUpdateData.begin(); i != vecUpdateData.end(); i++)
-//     {
-//         bool bCheckDependencies = false;
-//         if ( dep.is()) // in recursion
-//         {
-//             if (dp_misc::getIdentifier(i->aInstalledExtension).equals(idRequired))
-//             {
-//                 if (dp_misc::compareVersions( i->updateVersion, minVersion) != dp_misc::LESS )
-//                     bCheckDependencies = true;
-//                 else
-//                     //There is only one extension per identifier in the vecUpdateData
-//                     //We found one but it has no suitable version
-//                     break;
-//             }
-//         }
-//         if (!dep.is()) // First call
-//             bCheckDependencies = true;
-        
-        
-//         if (bCheckDependencies)
-//         {
-//             if (!i->dependencySolved)
-//             {
-//                 ret = true;
-//                 //Found the required extension with a suitable version. Now check if
-//                 //this extension has satisfied dependencies, otherwise we cannot use
-//                 //it.
-//                 //collect the unsolved dependencies in this vector and replace with it
-//                 //UpdateData.unsatisfiedDependencies later on.
-//                 ::std::vector<uno::Reference<xml::dom::XElement> > vecUnsolvedAll;
-//                 ::std::vector<uno::Reference<xml::dom::XElement> > vecRequiredUpdates;
-//                 for (sal_Int32 ii = 0; ii < i->unsatisfiedDependencies.getLength(); ii++)
-//                 {
-//                     uno::Reference<xml::dom::XElement> const & dep2 =
-//                         i->unsatisfiedDependencies[ii];
-//                     if (!solveDependency(dep2, vecUpdateData))
-//                         vecUnsolvedAll.push_back(dep2);
-//                     else if (isInterExtensionDependency(dep2))
-//                         vecRequiredUpdates.push_back(dep2);
-//                 }
-//                 i->unsatisfiedDependencies = ::comphelper::containerToSequence(vecUnsolvedAll);
-//                 i->requiredUpdates = vecRequiredUpdates;
-//                 if (i->unsatisfiedDependencies.getLength())
-//                     ret &= false;
-//                 i->dependencySolved = true;
-//             }
-//             else
-//             {
-//                 ret = i->unsatisfiedDependencies.getLength() ? false : true;
-                    
-//             }
-//             if (dep.is()) // in recursion,
-//                 break;
-//         }
-//     }
-
-//     // vecUpdateData does not contain an extension with a particular id.
-//     if (dep.is() && bNoExtensionWithRequiredIdentifier)
-//     {
-//     }
-//     return ret;
-// }
-//
-//The vector vecUpdateData contains information about all available
-//online updates. If vecUpdateData.unsatisfiedDependencies contains entries, then
-//it is no valid update, because its dependencies are not satisfied. However, it
-//can have entries which represent an unsatisfied inter-extension dependency. We try
-//to solve those cases where the required extension is another update and was
-//therefore not considered by the dp_misc::Dependencies::check function. It only
-//uses installed extensions when checking.
-//
-void UpdateDialog::Thread::fixInterExtensionDependencies(
-    ::std::vector< dp_gui::UpdateData> & vecUpdateData)
-{
-    // solveDependency(uno::Reference<xml::dom::XElement>(), vecUpdateData);
-}
-
-
-//todo version
 /*
   @identifier
   the extension identifier representing the extension which needs
 bool UpdateDialog::Thread::solveDependency(
     uno::Reference<xml::dom::XElement> const & dependency,
     dp_misc::UpdateInfoMap const & updateInfos,
-    dp_misc::UpdateInfoMap  & inout_requiredUpdates,
+    RequiredUpdatesMap  & inout_requiredUpdates,
     ::std::vector< uno::Reference<xml::dom::XElement> > &
     inout_failedDeps) const
 {
     //We can only handle inter-extension dependencies
-    if (!isInterExtensionDependency(dependency))
+    if (!dp_misc::Dependencies::isInterExtensionDependency(dependency))
     {
         inout_failedDeps.push_back(dependency);
         return false;
     //See if we have information about the requested extension
     const ::rtl::OUString identifier = dependency->getAttribute(OUSTR("identifier"));
     OSL_ASSERT(identifier.getLength());
-    dp_misc::UpdateInfoMap::const_iterator it_upd_infos =
+    dp_misc::UpdateInfoMap::const_iterator it_upd_info =
         updateInfos.find(identifier);
-    if (it_upd_infos == updateInfos.end())
+    if (it_upd_info == updateInfos.end())
     {
         //There are no information about the required extension available.
         inout_failedDeps.push_back(dependency);
         //Required extension exist. Is its version sufficient?
         const ::rtl::OUString requiredVersion = dependency->getAttribute(OUSTR("minimum-version"));
         OSL_ASSERT(requiredVersion.getLength());
-        dp_misc::DescriptionInfoset infoUpdate(m_context, it_upd_infos->second);
+        dp_misc::DescriptionInfoset infoUpdate(m_context, it_upd_info->second);
         if(dp_misc::compareVersions(infoUpdate.getVersion() , requiredVersion) == dp_misc::LESS)
         {
             inout_failedDeps.push_back(dependency);
     }
 
     //Has the extension unsatisfied dependencies?
-    dp_misc::DescriptionInfoset  infoset(m_context, it_upd_infos->second);
+    dp_misc::DescriptionInfoset  infoset(m_context, it_upd_info->second);
     uno::Sequence<uno::Reference<xml::dom::XElement> > seqUnsatisfiedDependencies =
         dp_misc::Dependencies::check(m_context, infoset);
 
-    //Solve them recursively
+//    Solve them recursively
     bool bAllSolved = true;
     for (sal_Int32 i = 0; i < seqUnsatisfiedDependencies.getLength(); i++)
     {
             inout_failedDeps);
     }
     if (bAllSolved)
-        inout_requiredUpdates.insert(*it_upd_infos);
+    {
+        dp_misc::DescriptionInfoset info(
+            m_context, uno::Reference<xml::dom::XNode>(dependency, uno::UNO_QUERY_THROW));
+        ::std::pair< ::rtl::OUString, uno::Reference<xml::dom::XNode> > mapValue(
+            info.getLocalizedDisplayName(),it_upd_info->second);
+        
+        inout_requiredUpdates[it_upd_info->first] = mapValue;
+    }
     return bAllSolved;
 }
 
 ::std::vector<dp_gui::UpdateData> 
-UpdateDialog::Thread::getUpdateData(dp_misc::UpdateInfoMap const & updateInformation) const
+UpdateDialog::Thread::getUpdateData() const
 {
     ::std::vector<dp_gui::UpdateData> vecUpData;
+    
+    std::vector<std::pair<uno::Reference<deployment::XPackage>, uno::Any > > errors;
+    dp_misc::UpdateInfoMap updateInformation = dp_misc::getOnlineUpdateInfos(
+        m_context, m_extensionMgr, m_updateInformation, m_vExtensionList, errors);
+
+    typedef std::vector<std::pair<uno::Reference<deployment::XPackage>,
+        uno::Any> >::const_iterator ITERROR;
+    for (ITERROR ite = errors.begin(); ite != errors.end(); ite ++)
+        handleSpecificError(ite->first, ite->second);
+
     typedef ::std::vector<uno::Reference<deployment::XPackage> >::const_iterator CIT_EXT;
     //iterate over all extensions for which we want an update and return the 
     //corresponding update information
             if (dp_misc::compareVersions((*i)->getVersion(), infoSetUpdate.getVersion())
                 == dp_misc::LESS)
             {
+                const uno::Sequence<uno::Reference<xml::dom::XElement> > dependencies =
+                    dp_misc::Dependencies::check(m_context, infoSetUpdate);
+
+                bool bShared = (*i)->getRepositoryName().equals(OUSTR("shared"));
+                ::std::vector<uno::Reference<xml::dom::XElement> > vecUnsolvedDeps;
+                ::std::vector<uno::Reference<xml::dom::XElement> > vecRequiredExtensions;
+                //Iterate over all dependencies
+                for (sal_Int32 idep = 0; idep < dependencies.getLength(); idep++)
                 {
-                    const uno::Sequence<uno::Reference<xml::dom::XElement> > dependencies =
-                        dp_misc::Dependencies::check(m_context, infoSetUpdate);
+                    uno::Reference<xml::dom::XElement> const & cur_dep =
+                        dependencies[idep];
                     
-                    ::std::vector<uno::Reference<xml::dom::XElement> > vecUnsolvedDeps;
-                    ::std::vector<uno::Reference<xml::dom::XElement> > vecRequiredExtensions;
-                    for (sal_Int32 idep = 0; idep < dependencies.getLength(); idep++)
+                    RequiredUpdatesMap mapRequiredUpdates;
+                    dp_misc::UpdateInfoMap mapUnsolved;
+                    ::std::vector< uno::Reference<xml::dom::XElement> > vecUnknown;
+                    
+                    if (solveDependency(
+                            cur_dep, updateInformation, mapRequiredUpdates,
+                            vecUnknown))
                     {
-                        uno::Reference<xml::dom::XElement> const & cur_dep =
-                            dependencies[idep];
-                        dp_misc::UpdateInfoMap mapRequiredUpdates;
-                        dp_misc::UpdateInfoMap mapUnsolved;
-                        ::std::vector< uno::Reference<xml::dom::XElement> > vecUnknown;
-
-                        if (solveDependency(
-                                cur_dep, updateInformation, mapRequiredUpdates,
-                                vecUnknown))
+                        vecRequiredExtensions.push_back(cur_dep);
+                        //Determine if the required updates are already in the
+                        //m_vExtensionList. If not then we create an additional
+                        //UpdateData.
+                        typedef RequiredUpdatesMap::const_iterator CIT_REQ;
+                        for (CIT_REQ i_req = mapRequiredUpdates.begin();
+                             i_req != mapRequiredUpdates.end(); i_req++)
                         {
-                            //Determine if the required updates are already in the
-                            //m_vExtensionList. If not then we create an additional
-                            //UpdateData.
-                            typedef dp_misc::UpdateInfoMap::const_iterator CIT_REQ;
-                            for (CIT_REQ i_req = mapRequiredUpdates.begin();
-                                  i_req != mapRequiredUpdates.end(); i_req++)
+                            ::std::vector<uno::Reference<deployment::XPackage> >::const_iterator iext =
+                                ::std::find_if(m_vExtensionList.begin(), m_vExtensionList.end(),
+                                               MatchExtensionWithDependency(i_req->second.second));
+                            if (iext == m_vExtensionList.end())
                             {
-                                ::std::vector<uno::Reference<deployment::XPackage> >::const_iterator iext =
-                                    ::std::find_if(m_vExtensionList.begin(), m_vExtensionList.end(),
-                                                   MatchExtensionWithDependency(i_req->second));
-                                if (iext == m_vExtensionList.end())
+                                //Also look in vecUpData if it was already added
+                                //We only need to look for the identifier, because there is always
+                                //only one extension  with a particular identifier in the map
+                                //that we get with getOnlineUpdateInfos
+                                dp_misc::DescriptionInfoset infoReqExt(
+                                    m_context, i_req->second.second);
+                                ::boost::optional< ::rtl::OUString> id = infoReqExt.getIdentifier();
+                                if (id)
                                 {
-//                                     //ToDo: also look in vecUpData if it was already added
-//                                     dp_misc::DescriptionInfoset infoReqExt(m_context, i_req->second);
-//                                     ::boost::optional< ::rtl::OUString> id = infoReqExt.getIdentifier();
-//                                     if (id)
-//                                     {
-//                                         UpdateData data(*id);
-//                                         vecUpData.push_back();
-//                                     }
+                                    ::std::vector<UpdateData>::const_iterator iupdata =
+                                        ::std::find_if(vecUpData.begin(), vecUpData.end(),
+                                                       MatchUpdateData(*id));
+                                    if (iupdata == vecUpData.end())
+                                    {
+                                        UpdateData data(m_context, i_req->second.first,
+                                                        i_req->second.second, bShared);
+                                        vecUpData.push_back(data);
+                                    }
                                 }
                             }
                         }
-                        else
-                        {
-                            //solveDependency can fail because of
-                            // -an unsolved dependency
-                            // -no update information for an required extension
-                            // -the version of the available updates is not higher
-                            //  than that of the installed extension
-                            typedef ::std::vector< uno::Reference<xml::dom::XElement> >::const_iterator IUnknown;
-                            for (IUnknown iu = vecUnknown.begin(); iu != vecUnknown.end(); iu++)
-                                vecUnsolvedDeps.push_back(*iu);
-                        }
                     }
-                    //if all solved construct UpdateData
-                    UpdateData data(m_context, *i, it_upInfo->second, vecUnsolvedDeps,
-                                    vecRequiredExtensions);
-                    vecUpData.push_back(data);
+                    else
+                    {
+                        //solveDependency can fail because of
+                        // -an unsolved dependency
+                        // -no update information for an required extension
+                        // -the version of the available updates is not higher
+                        //  than that of the installed extension
+                        // Improvement: show if a required extension (e.g. one for which there
+                        // is a dependency) failes because of those 3 error causes
+                        typedef ::std::vector< uno::Reference<xml::dom::XElement> >::const_iterator IUnknown;
+                        for (IUnknown iu = vecUnknown.begin(); iu != vecUnknown.end(); iu++)
+                            vecUnsolvedDeps.push_back(*iu);
+                    }
                 }
+                //if all solved construct UpdateData
+                UpdateData data(m_context, *i, it_upInfo->second, vecUnsolvedDeps,
+                                vecRequiredExtensions, bShared);
+                vecUpData.push_back(data);
             }
         }
      }
             return;
         }
     }
-    uno::Reference<deployment::XExtensionManager> extMgr =
-        deployment::ExtensionManager::get(m_context);
-
-    std::vector<std::pair<uno::Reference<deployment::XPackage>, uno::Any > > errors;
-    
-    dp_misc::UpdateInfoMap updateInfoMap = dp_misc::getOnlineUpdateInfos(
-        m_context, extMgr, m_updateInformation, m_vExtensionList, errors);
-
-    typedef std::vector<std::pair<uno::Reference<deployment::XPackage>,
-        uno::Any> >::const_iterator ITERROR;
-    for (ITERROR ite = errors.begin(); ite != errors.end(); ite ++)
-        handleSpecificError(ite->first, ite->second);
-
-    ::std::vector<dp_gui::UpdateData> vecUpdateData =
-          getUpdateData(updateInfoMap);
-    
-
-    //See if there are still extensions with unsatisfied inter-extension dependencies.
-    //This can be the case if one only wants to update one extension which requires
-    //other extensions or an update requires extensions which are not yet installed.
-    
-    
+    ::std::vector<dp_gui::UpdateData> vecUpdateData = getUpdateData();    
     typedef ::std::vector< UpdateData>::const_iterator CIT;
 
+    //Every entry in vecUpdateData will be displayed in the dialog. An entry
+    //can represent an update for an existing extension or a completey new
+    //extension which is required by an update.
+    //An entry can also be a "disabled update" because there are unsatisfied
+    //dependencies.
     for (CIT ii = vecUpdateData.begin(); ii != vecUpdateData.end(); ii++)
     {
         UpdateData updateData = *ii;
         rtl::OUString sVersionUser;
         rtl::OUString sVersionShared;
         rtl::OUString sVersionBundled;
-        uno::Sequence< uno::Reference< deployment::XPackage> > extensions;
+        uno::Sequence< uno::Reference< deployment::XPackage> > extensions(3);
         try {
-            extensions = extMgr->getExtensionsWithSameIdentifier(
-                dp_misc::getIdentifier(updateData.aInstalledExtension),
-                updateData.aInstalledExtension->getName(),
+            extensions = m_extensionMgr->getExtensionsWithSameIdentifier(
+                updateData.identifier, ::rtl::OUString(),
                 uno::Reference<ucb::XCommandEnvironment>());
         } catch (lang::IllegalArgumentException& ) {
-            OSL_ASSERT(0);
-            continue;
+            //vecUpdateData can contain UpdateData representing extension which are available
+            //online an which are not yet installed.
         } catch (css::ucb::CommandFailedException& ) {
             OSL_ASSERT(0);
             continue;
         if (extensions[2].is() )
             sVersionBundled = extensions[2]->getVersion();
             
-        bool bSharedReadOnly = extMgr->isReadOnlyRepository(OUSTR("shared"));
+        bool bSharedReadOnly = m_extensionMgr->isReadOnlyRepository(OUSTR("shared"));
+        //We expect that there are only updates for the shared repository if one
+        //can write to it.
+        if (bSharedReadOnly && ii->bIsShared)
+        {
+            OSL_ASSERT(0);
+            continue;
+        }
         //If there is no online update or there is one but the dependency check
         //failed, then sOnlineVersion is an empty string.        
         //Determine if the update is installed in the user repository and from where
         //is is taken, that is from the online, shared or bundled repository.
-        dp_misc::UPDATE_SOURCE sourceUser = dp_misc::isUpdateUserExtension(
-            bSharedReadOnly, sVersionUser, sVersionShared, sVersionBundled, sOnlineVersion);
-        dp_misc::UPDATE_SOURCE sourceShared = dp_misc::isUpdateSharedExtension(
-            bSharedReadOnly, sVersionShared, sVersionBundled, sOnlineVersion);
-
-        uno::Reference<deployment::XPackage> updateSource;
-
-        if (sourceUser == dp_misc::UPDATE_SOURCE_SHARED)
+        // dp_misc::UPDATE_SOURCE sourceUser = dp_misc::isUpdateUserExtension(
+        //     bSharedReadOnly, sVersionUser, sVersionShared, sVersionBundled, sOnlineVersion);
+        // dp_misc::UPDATE_SOURCE sourceShared = dp_misc::isUpdateSharedExtension(
+        //     bSharedReadOnly, sVersionShared, sVersionBundled, sOnlineVersion);
+        int highestUser = dp_misc::determineHighestVersion(
+            sVersionUser, sVersionShared, sVersionBundled, sOnlineVersion);
+        int highestShared = dp_misc::determineHighestVersion(
+            ::rtl::OUString(), sVersionShared, sVersionBundled, sOnlineVersion);
+        
+        if (highestUser == 1) // source is SHARED
         {
             //The local update source is always the same or better than
             //the online update and has satisfied dependendencies. Otherwise
             updateData.aUpdateSource = extensions[1];
             updateData.updateVersion = extensions[1]->getVersion();
         }
-        else if (sourceUser == dp_misc::UPDATE_SOURCE_BUNDLED)
+        else if (highestUser == 2) //source is BUNDLED
         {
             updateData.unsatisfiedDependencies.clear();
             updateData.requiredUpdates.clear();
             updateData.updateVersion = extensions[2]->getVersion();
         }
         
-        if (sourceShared == dp_misc::UPDATE_SOURCE_BUNDLED)
+        if (highestShared == 2) //source is BUNDLED
         {
             updateData.unsatisfiedDependencies.clear();
             updateData.requiredUpdates.clear();
-            updateData.bIsShared = true;
+            //          updateData.bIsShared = true;
             updateData.aUpdateSource = extensions[2];
             updateData.updateVersion = extensions[2]->getVersion();
         }
-        else if (sourceShared == dp_misc::UPDATE_SOURCE_ONLINE)
-        {
-            updateData.bIsShared = true;
-        }
 
-        if (sourceShared != dp_misc::UPDATE_SOURCE_NONE ||
-            sourceUser != dp_misc::UPDATE_SOURCE_NONE)
-        {
-            update(updateData);
-        }
-        else if(sourceShared == dp_misc::UPDATE_SOURCE_NONE &&
-                sourceUser == dp_misc::UPDATE_SOURCE_NONE
-                && updateData.unsatisfiedDependencies.size())
-        {    
-            //Even show the possible update if it has unsatisfied dependencies
-            //which may only happen with online updates.
-            //It must have a greater version than the installed one
-            dp_misc::UPDATE_SOURCE sourceUser = dp_misc::isUpdateUserExtension(
-                bSharedReadOnly, sVersionUser, sVersionShared, sVersionBundled,
-                updateData.onlineVersion);
-            dp_misc::UPDATE_SOURCE sourceShared = dp_misc::isUpdateSharedExtension(
-                bSharedReadOnly, sVersionShared, sVersionBundled, updateData.onlineVersion);
-            if (sourceUser == dp_misc::UPDATE_SOURCE_ONLINE
-                || sourceShared == dp_misc::UPDATE_SOURCE_ONLINE)
-                update(updateData);
-        }
+        update(updateData);
+
+        // if (sourceShared != dp_misc::UPDATE_SOURCE_NONE ||
+        //     sourceUser != dp_misc::UPDATE_SOURCE_NONE)
+        // {
+        //     update(updateData);
+        // }
+        // else if(sourceShared == dp_misc::UPDATE_SOURCE_NONE &&
+        //         sourceUser == dp_misc::UPDATE_SOURCE_NONE
+        //         && updateData.unsatisfiedDependencies.size())
+        // {    
+        //     //Even show the possible update if it has unsatisfied dependencies
+        //     //which may only happen with online updates.
+        //     //It must have a greater version than the installed one
+        //     dp_misc::UPDATE_SOURCE sourceUser = dp_misc::isUpdateUserExtension(
+        //         bSharedReadOnly, sVersionUser, sVersionShared, sVersionBundled,
+        //         updateData.onlineVersion);
+        //     dp_misc::UPDATE_SOURCE sourceShared = dp_misc::isUpdateSharedExtension(
+        //         bSharedReadOnly, sVersionShared, sVersionBundled, updateData.onlineVersion);
+        //     if (sourceUser == dp_misc::UPDATE_SOURCE_ONLINE
+        //         || sourceShared == dp_misc::UPDATE_SOURCE_ONLINE)
+        //         update(updateData);
+        // }
 
         //ToDo: handle the case that there is a local update AND a online update
         //with a better version but unsatisfied dependencies
 ::rtl::OUString UpdateDialog::Thread::getUpdateDisplayString(
     dp_gui::UpdateData const & data, ::rtl::OUString const & version) const
 {
-    OSL_ASSERT(data.aInstalledExtension.is());
-    rtl::OUStringBuffer b(data.aInstalledExtension->getDisplayName());
+    rtl::OUStringBuffer b(data.name);
     b.append(static_cast< sal_Unicode >(' '));
     {
         vos::OGuard g( Application::GetSolarMutex() );
         vos::OGuard g(Application::GetSolarMutex());
         if (!m_stop) {
             m_dialog.addDisabledUpdate(
-                DisabledUpdate(data.sUpdateDisplayString,
-                               dp_misc::getIdentifier(data.aInstalledExtension),
+                DisabledUpdate(data.sUpdateDisplayString, data.identifier,
                                ::comphelper::containerToSequence(data.unsatisfiedDependencies),
                     data.aUpdateInfo));
         }
                                      dp_gui::UpdateData & data )
 {
     USHORT nIndex = sal::static_int_cast< USHORT >( m_enabledUpdates.size() );
-    UpdateDialog::Index *pEntry = new UpdateDialog::Index( ENABLED_UPDATE, nIndex, name,
-                                                           dp_misc::getIdentifier(data.aInstalledExtension));
+    UpdateDialog::Index *pEntry = new UpdateDialog::Index(
+        ENABLED_UPDATE, nIndex, name, data.identifier);
     m_enabledUpdates.push_back( data );
     m_ListboxEntries.push_back( pEntry );
 
             if ( p->m_eKind == ENABLED_UPDATE )
             {
                 dp_gui::UpdateData aUpdData = m_enabledUpdates[ p->m_nIndex ];
-                aItem[0] = dp_misc::getIdentifier( aUpdData.aInstalledExtension );
+                aItem[0] = aUpdData.identifier;
     
                 dp_misc::DescriptionInfoset aInfoset( m_context, aUpdData.aUpdateInfo );
                 aItem[1] = aInfoset.getVersion();
         if ( index->m_eKind == ENABLED_UPDATE )
         {
             dp_gui::UpdateData aUpdData = m_enabledUpdates[ index->m_nIndex ];
-            aExtensionID = dp_misc::getIdentifier( aUpdData.aInstalledExtension );
+            aExtensionID = aUpdData.identifier;
             aVersion = aUpdData.updateVersion;
         }
         else if ( index->m_eKind == DISABLED_UPDATE )
     if ( pIndex->m_eKind == ENABLED_UPDATE )
     {
         dp_gui::UpdateData aUpdData = m_enabledUpdates[ pIndex->m_nIndex ];
-        aExtensionID = dp_misc::getIdentifier( aUpdData.aInstalledExtension );
+        aExtensionID = aUpdData.identifier;
         if ( !bIgnoreAll )
             aVersion = aUpdData.updateVersion;
     }
         for (CIT i = curData.requiredUpdates.begin(); i != curData.requiredUpdates.end(); i++)
         {
             //We have the XElement which describes the dependency. Use it to get the
-            //corresponding UpdateData from the vecUnorderedUpdates. It must be contained
-            //otherwise this extension would not have been checked in the dialog
+            //corresponding UpdateData from the vecUnorderedUpdates. If it is
+            //not in vecUnorderedUpdates then it is already installed.
             ::std::vector<dp_gui::UpdateData>::const_iterator iUpData =
                 ::std::find_if(vecUnorderedUpdates.begin(), vecUnorderedUpdates.end(),
                                MatchUpdateData((*i)->getAttribute(OUSTR("identifier"))));
-            OSL_ASSERT(iUpData != vecUnorderedUpdates.end());
             if (iUpData != vecUnorderedUpdates.end())
                 addUpdateSorted(*iUpData, vecUnorderedUpdates);
         }
         pEntry = static_cast< UpdateDialog::Index const * >(
             m_updates.GetEntryData(i++));
         if (pEntry != NULL
-            && pEntry->m_identifier.equals(dp_misc::getIdentifier(data.aInstalledExtension)))
+            && pEntry->m_identifier.equals(data.identifier))
             break;
     }
     while (pEntry != NULL);
     typedef ::std::vector<UpdateData>::const_iterator CIT;
     for (CIT i = m_enabledUpdates.begin(); i < m_enabledUpdates.end(); i++)
     {
-        OSL_ASSERT(i->aInstalledExtension.is());
         //If the user has no write access to the shared folder then the update
         //for a shared extension is disable, that is it cannot be in m_enabledUpdates
-        //       OSL_ASSERT(isReadOnly(i->aInstalledPackage) == sal_False);
 #if 0
         // TODO: check!
         OSL_ASSERT(m_extensionManagerDialog.get());

File desktop/source/deployment/gui/dp_gui_updateinstalldialog.cxx

     // guarded by Application::GetSolarMutex():
     cssu::Reference< css::task::XAbortChannel > m_abort;
     cssu::Reference< cssu::XComponentContext > m_xComponentContext;
+    cssu::Reference< css::deployment::XExtensionManager > m_xExtensionManager;
     std::vector< dp_gui::UpdateData > & m_aVecUpdateData;
     ::rtl::Reference<UpdateCommandEnv> m_updateCmdEnv;
 
     m_aVecUpdateData(aVecUpdateData),
     m_updateCmdEnv(new UpdateCommandEnv(xCtx, m_dialog, this)),
     m_stop(false)
-{}
+{
+    m_xExtensionManager = css::deployment::ExtensionManager::get(m_xComponentContext);
+}
 
 void UpdateInstallDialog::Thread::stop() {
     cssu::Reference< css::task::XAbortChannel > abort;
                 if (m_stop) {
                     return;
                 }
-                m_dialog.m_ft_extension_name.SetText(curData.aInstalledExtension->getDisplayName());
+                m_dialog.m_ft_extension_name.SetText(curData.name);
                 sal_uInt16 prog = (sal::static_int_cast<sal_uInt16>(100) * ++count) /
                     sal::static_int_cast<sal_uInt16>(m_aVecUpdateData.size());
                 m_dialog.m_statusbar.SetValue(prog);
                         buf.appendAscii(". ");
                         buf.append(j->second.Message);
                     }
-                    m_dialog.setError(UpdateInstallDialog::ERROR_DOWNLOAD, curData.aInstalledExtension->getDisplayName(), 
+                    m_dialog.setError(UpdateInstallDialog::ERROR_DOWNLOAD, curData.name, 
                         buf.makeStringAndClear());
                 }
             }
                 (sal::static_int_cast<sal_uInt16>(100) * count) /
                 sal::static_int_cast<sal_uInt16>(m_aVecUpdateData.size()));
              }
-            m_dialog.m_ft_extension_name.SetText(i->aInstalledExtension->getDisplayName());
+            m_dialog.m_ft_extension_name.SetText(i->name);
         }
 //         TimeValue v = {1, 0};
 //       osl::Thread::wait(v);
         try
         {
             cssu::Reference< css::task::XAbortChannel > xAbortChannel(
-                curData.aInstalledExtension->createAbortChannel() );
+                m_xExtensionManager->createAbortChannel() );
             {
                 vos::OGuard g(Application::GetSolarMutex());
                 if (m_stop) {
                 return;
             }
             m_dialog.setError(UpdateInstallDialog::ERROR_LICENSE_DECLINED, 
-                curData.aInstalledExtension->getDisplayName(), OUString());
+                curData.name, OUString());
         }
         else if (!xExtension.is() || bError)
         {
                 return;
             }
             m_dialog.setError(UpdateInstallDialog::ERROR_INSTALLATION, 
-                curData.aInstalledExtension->getDisplayName(), exc.Message);
+                curData.name, exc.Message);
         }
     }
     {

File desktop/source/deployment/inc/dp_dependencies.hxx

         ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference<
         ::com::sun::star::deployment::XPackage> > & out_failingExtensions);
 
+    DESKTOP_DEPLOYMENTMISC_DLLPUBLIC 
+    bool isInterExtensionDependency(
+        ::com::sun::star::uno::Reference< ::com::sun::star::xml::dom::XElement > const & dep);
 
 } //namespace Dependencies
 } //namespace dp_misc

File desktop/source/deployment/inc/dp_update.hxx

     ::std::vector< ::std::pair< ::com::sun::star::uno::Reference<
     ::com::sun::star::deployment::XPackage>, ::com::sun::star::uno::Any> > & out_errors);
 
-/* retunrs the highest version from the provided arguments.
+/* returns the highest version from the provided arguments.
 */
 DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
 ::rtl::OUString getHighestVersion(
     ::rtl::OUString const & bundledVersion,
     ::rtl::OUString const & onlineVersion);
 
+/* returns the index of the parameter with the highest version.
+   The index starts at 0.
+*/
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
+int determineHighestVersion(
+    ::rtl::OUString const & userVersion,
+    ::rtl::OUString const & sharedVersion,
+    ::rtl::OUString const & bundledVersion,
+    ::rtl::OUString const & onlineVersion);
+
 }
 
 #endif

File desktop/source/deployment/misc/dp_dependencies.cxx

     return ret;
 }
 
+bool isInterExtensionDependency(
+    css::uno::Reference< css::xml::dom::XElement > const & e)
+{
+    if (e->getNamespaceURI().equalsAsciiL(
+            RTL_CONSTASCII_STRINGPARAM("http://openoffice.org/extensions/description/2006"))
+        && e->getTagName().equalsAsciiL(
+            RTL_CONSTASCII_STRINGPARAM("extension")))
+    {
+        return true;
+    }
+    return false;
+}
+
 
 }
 

File desktop/source/deployment/misc/dp_update.cxx

 namespace dp_misc {
 namespace {
 
-int determineHighestVersion(
-    ::rtl::OUString const & userVersion,
-    ::rtl::OUString const & sharedVersion,
-    ::rtl::OUString const & bundledVersion,
-    ::rtl::OUString const & onlineVersion)
-{
-    int index = 0;
-    OUString  greatest = userVersion;
-    if (dp_misc::compareVersions(sharedVersion, greatest) == dp_misc::GREATER)
-    {
-        index = 1;
-        greatest = sharedVersion;
-    }
-    if (dp_misc::compareVersions(bundledVersion, greatest) == dp_misc::GREATER)
-    {
-        index = 2;
-        greatest = bundledVersion;
-    }
-    if (dp_misc::compareVersions(onlineVersion, greatest) == dp_misc::GREATER)
-    {
-        index = 3;
-    }
-    return index;
-}
 
 Sequence< Reference< xml::dom::XElement > >
 getUpdateInformation( Reference<deployment::XUpdateInformationProvider > const & updateInformation,
     }
     else
     {
-        if (userVersion.getLength())
-        {
+        // if (userVersion.getLength())
+        // {
             int index = determineHighestVersion(
                 userVersion, sharedVersion, bundledVersion, onlineVersion);
             if (index == 1)
                 retVal = UPDATE_SOURCE_BUNDLED;
             else if (index == 3)
                 retVal = UPDATE_SOURCE_ONLINE;
-        }
+//        }
     }
         
     return retVal;
         getDefaultUpdateInfos(xContext, updateInformation, setExtWithOwnUrls, infoMap, out_errors);
     return infoMap;
 }
+
+int determineHighestVersion(
+    ::rtl::OUString const & userVersion,
+    ::rtl::OUString const & sharedVersion,
+    ::rtl::OUString const & bundledVersion,
+    ::rtl::OUString const & onlineVersion)
+{
+    int index = 0;
+    OUString  greatest = userVersion;
+    if (dp_misc::compareVersions(sharedVersion, greatest) == dp_misc::GREATER)
+    {
+        index = 1;
+        greatest = sharedVersion;
+    }
+    if (dp_misc::compareVersions(bundledVersion, greatest) == dp_misc::GREATER)
+    {
+        index = 2;
+        greatest = bundledVersion;
+    }
+    if (dp_misc::compareVersions(onlineVersion, greatest) == dp_misc::GREATER)
+    {
+        index = 3;
+    }
+    return index;
+}
+
 OUString getHighestVersion(
     ::rtl::OUString const & userVersion,
     ::rtl::OUString const & sharedVersion,

File desktop/source/pkgchk/unopkg/unopkg_cmdenv.cxx

         {
             
             sMsg = sMsg + dp_misc::Dependencies::getErrorText(
-                info, depExc.UnsatisfiedDependencies[i]) + OUSTR("\n");;
+                m_xComponentContext, depExc.UnsatisfiedDependencies[i]) + OUSTR("\n");;
         }
         dp_misc::writeConsole(OUSTR("\n") + sMsg);