- logging "reverse" NEEDED_BY in the detail description of solver
[platform/upstream/libzypp.git] / zypp / solver / detail / SolutionAction.cc
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
2 /* SolutionAction.cc
3  *
4  * Easy-to use interface to the ZYPP dependency resolver
5  *
6  * Copyright (C) 2000-2002 Ximian, Inc.
7  * Copyright (C) 2005 SUSE Linux Products GmbH
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License,
11  * version 2, as published by the Free Software Foundation.
12  *
13  * This program is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21  * 02111-1307, USA.
22  */
23
24 #include "zypp/solver/detail/Resolver.h"
25 #include "zypp/solver/detail/SolutionAction.h"
26 #include "zypp/CapSet.h"
27 #include "zypp/base/Logger.h"
28 #include "zypp/Dependencies.h"
29
30
31 /////////////////////////////////////////////////////////////////////////
32 namespace zypp
33 { ///////////////////////////////////////////////////////////////////////
34   ///////////////////////////////////////////////////////////////////////
35   namespace solver
36   { /////////////////////////////////////////////////////////////////////
37     /////////////////////////////////////////////////////////////////////
38     namespace detail
39     { ///////////////////////////////////////////////////////////////////
40
41 using namespace std;
42
43 IMPL_PTR_TYPE(SolutionAction);
44 IMPL_PTR_TYPE(TransactionSolutionAction);
45 IMPL_PTR_TYPE(InjectSolutionAction);
46
47 //---------------------------------------------------------------------------
48
49 SolutionAction::SolutionAction()
50 {
51 }
52
53
54 SolutionAction::~SolutionAction()
55 {
56 }
57
58
59 //---------------------------------------------------------------------------
60
61 ostream &
62 TransactionSolutionAction::dumpOn( ostream& os) const
63 {
64     os << "TransactionSolutionAction: ";
65     switch (_action) {
66         case KEEP:      os << "Keep"; break;
67         case INSTALL:   os << "Install"; break;
68         case REMOVE:    os << "Remove"; break;
69         case UNLOCK:    os << "Unlock"; break;
70         case ALLBRANCHES_ON:    os << "All branches on"; break;
71         case ALLBRANCHES_OFF:   os << "All branches off"; break;            
72         case DOUBLETIMEOUT:     os << "Double timeout"; break;
73     }
74     os << " ";
75     os << _item;
76     os << endl;
77     return os;
78 }
79
80
81 ostream&
82 operator<<( ostream& os, const SolutionActionList & actionlist)
83 {
84     for (SolutionActionList::const_iterator iter = actionlist.begin(); iter != actionlist.end(); ++iter) {
85         os << *(*iter);
86         os << endl;
87     }
88     return os;
89 }
90
91
92 ostream&
93 operator<<( ostream& os, const CSolutionActionList & actionlist)
94 {
95     for (CSolutionActionList::const_iterator iter = actionlist.begin(); iter != actionlist.end(); ++iter) {
96         os << *(*iter);
97         os << endl;
98     }
99     return os;
100 }
101
102 //---------------------------------------------------------------------------
103
104 ostream &
105 InjectSolutionAction::dumpOn( ostream& os ) const
106 {
107     os << "InjectSolutionAction: ";
108     os << _capability;
109     os << ", ";
110     switch (_kind) {
111         case REQUIRES:  os << "Requires"; break;
112         case CONFLICTS: os << "Conflicts"; break;
113         case OBSOLETES: os << "Obsoletes"; break;
114         case INSTALLED: os << "Installed"; break;
115         case ARCHITECTURE: os << "Architecture"; break;
116         case VENDOR: os << "Vendor"; break;                 
117         default: os << "Wrong kind"; break;
118     }
119     os << " ";
120     os << _item;            
121     os << endl;
122     return os;
123 }
124
125 //---------------------------------------------------------------------------
126
127
128 ostream &
129 SolutionAction::dumpOn( std::ostream & os ) const
130 {
131     os << "SolutionAction<";
132     os << "not specified";
133     os << "> ";
134     return os;
135 }
136
137
138 bool 
139 TransactionSolutionAction::execute(Resolver & resolver) const
140 {
141     bool ret = true;
142     switch (action()) {
143         case KEEP:
144             resolver.addIgnoreInstalledItem( _item );
145             /*FALLTHRU*/
146         case INSTALL:
147             if (_item.status().isToBeUninstalled())
148                 ret = _item.status().setTransact (false, ResStatus::USER);
149             else
150                 _item.status().setToBeInstalled (ResStatus::USER);
151             break;
152         case REMOVE:
153             if (_item.status().isToBeInstalled()) {
154                 _item.status().setTransact (false,ResStatus::USER);
155                 _item.status().setLock (true,ResStatus::USER); // no other dependency can set it again          
156             } else if (_item.status().isInstalled())
157                 _item.status().setToBeUninstalled (ResStatus::USER);
158             else
159                 _item.status().setLock (true,ResStatus::USER); // no other dependency can set it again          
160             break;
161         case UNLOCK:
162             ret = _item.status().setLock (false, ResStatus::USER);
163             if (!ret) ERR << "Cannot unlock " << _item << endl;
164             break;
165         case ALLBRANCHES_ON:
166             resolver.setTryAllPossibilities (true);
167             break;
168         case ALLBRANCHES_OFF:
169             resolver.setTryAllPossibilities (false);
170             break;
171         case DOUBLETIMEOUT:
172             resolver.setTimeout (resolver.timeout()*2);
173             break;          
174         default:
175             ERR << "Wrong TransactionKind" << endl;
176             ret = false;
177     }
178     return ret;
179 }
180
181 bool
182 InjectSolutionAction::execute(Resolver & resolver) const
183 {
184     Dependencies dependencies;
185     CapSet depList;
186     if (_item != PoolItem_Ref()) {    
187         dependencies = _item.resolvable()->deps();
188         depList = dependencies[Dep::CONFLICTS];
189     }
190     switch (_kind) {
191         case CONFLICTS:
192             // removing conflict in both resolvables
193             for (CapSet::const_iterator iter = depList.begin(); iter != depList.end(); iter++) {
194                 if (iter->matches (_capability) == CapMatch::yes )
195                 {
196                     resolver.addIgnoreConflict (_item, _capability);
197                 }
198             }
199             // Obsoletes are conflicts too
200             depList = dependencies[Dep::OBSOLETES];
201             for (CapSet::const_iterator iter = depList.begin(); iter != depList.end(); iter++) {
202                 if (iter->matches (_capability) == CapMatch::yes )
203                 {
204                     resolver.addIgnoreConflict (_otherItem, _capability);
205                 }
206             }
207             
208             dependencies = _otherItem.resolvable()->deps();
209             depList = dependencies[Dep::CONFLICTS];
210             for (CapSet::const_iterator iter = depList.begin(); iter != depList.end(); iter++) {
211                 if (iter->matches (_capability) == CapMatch::yes )
212                 {
213                     resolver.addIgnoreConflict (_otherItem, _capability);
214                 }
215             }
216             // Obsoletes are conflicts too          
217             depList = dependencies[Dep::OBSOLETES];
218             for (CapSet::const_iterator iter = depList.begin(); iter != depList.end(); iter++) {
219                 if (iter->matches (_capability) == CapMatch::yes )
220                 {
221                     resolver.addIgnoreConflict (_otherItem, _capability);
222                 }
223             }
224             
225             break;
226         case REQUIRES:
227             // removing the requires dependency from the item
228             if (_item == PoolItem_Ref()) {
229                 // this was a requirement via Resolver::addExtraCapability
230                 // so we have to delete it.
231                 resolver.removeExtraCapability (_capability);
232             } else {
233                 resolver.addIgnoreRequires (_item, _capability);
234             }
235             break;
236         case ARCHITECTURE:
237             // This item is for ALL architectures available
238             resolver.addIgnoreArchitectureItem (_item);
239             break;
240         case VENDOR:
241             // This item is for ALL vendor available
242             resolver.addIgnoreVendorItem (_item);
243             break;                  
244         case OBSOLETES:
245             // removing the obsoletes dependency from the item
246             resolver.addIgnoreObsoletes (_otherItem, _capability);
247             break;          
248         case INSTALLED:
249             // ignoring already installed items
250             resolver.addIgnoreInstalledItem (_item);
251             resolver.addIgnoreInstalledItem (_otherItem);
252             break;
253         default:
254             ERR << "No valid InjectSolutionAction kind found" << endl;
255             return false;
256     }
257
258     return true;
259 }
260
261       ///////////////////////////////////////////////////////////////////
262     };// namespace detail
263     /////////////////////////////////////////////////////////////////////
264     /////////////////////////////////////////////////////////////////////
265   };// namespace solver
266   ///////////////////////////////////////////////////////////////////////
267   ///////////////////////////////////////////////////////////////////////
268 };// namespace zypp
269 /////////////////////////////////////////////////////////////////////////