001
014
015 package com.liferay.portal.service.impl;
016
017 import com.liferay.portal.LayoutFriendlyURLException;
018 import com.liferay.portal.LayoutNameException;
019 import com.liferay.portal.LayoutParentLayoutIdException;
020 import com.liferay.portal.LayoutTypeException;
021 import com.liferay.portal.NoSuchLayoutException;
022 import com.liferay.portal.kernel.bean.BeanReference;
023 import com.liferay.portal.kernel.bean.IdentifiableBean;
024 import com.liferay.portal.kernel.exception.PortalException;
025 import com.liferay.portal.kernel.exception.SystemException;
026 import com.liferay.portal.kernel.language.LanguageUtil;
027 import com.liferay.portal.kernel.util.FriendlyURLNormalizerUtil;
028 import com.liferay.portal.kernel.util.LocaleUtil;
029 import com.liferay.portal.kernel.util.StringPool;
030 import com.liferay.portal.kernel.util.Validator;
031 import com.liferay.portal.model.Group;
032 import com.liferay.portal.model.Layout;
033 import com.liferay.portal.model.LayoutConstants;
034 import com.liferay.portal.model.LayoutFriendlyURL;
035 import com.liferay.portal.model.LayoutSet;
036 import com.liferay.portal.model.LayoutSetPrototype;
037 import com.liferay.portal.model.ResourceConstants;
038 import com.liferay.portal.model.Role;
039 import com.liferay.portal.model.RoleConstants;
040 import com.liferay.portal.model.impl.LayoutImpl;
041 import com.liferay.portal.security.permission.ActionKeys;
042 import com.liferay.portal.service.ResourcePermissionLocalService;
043 import com.liferay.portal.service.RoleLocalServiceUtil;
044 import com.liferay.portal.service.persistence.LayoutFriendlyURLPersistence;
045 import com.liferay.portal.service.persistence.LayoutPersistence;
046 import com.liferay.portal.service.persistence.LayoutSetPersistence;
047 import com.liferay.portal.util.PortalUtil;
048 import com.liferay.portal.util.comparator.LayoutPriorityComparator;
049 import com.liferay.portlet.sites.util.SitesUtil;
050
051 import java.util.HashMap;
052 import java.util.List;
053 import java.util.Locale;
054 import java.util.Map;
055
056
059 public class LayoutLocalServiceHelper implements IdentifiableBean {
060
061 @Override
062 public String getBeanIdentifier() {
063 return _beanIdentifier;
064 }
065
066 public String getFriendlyURL(
067 long groupId, boolean privateLayout, long layoutId, String name,
068 String friendlyURL)
069 throws PortalException, SystemException {
070
071 friendlyURL = getFriendlyURL(friendlyURL);
072
073 if (Validator.isNotNull(friendlyURL)) {
074 return friendlyURL;
075 }
076
077 friendlyURL = StringPool.SLASH + getFriendlyURL(name);
078
079 String originalFriendlyURL = friendlyURL;
080
081 for (int i = 1;; i++) {
082 try {
083 validateFriendlyURL(
084 groupId, privateLayout, layoutId, friendlyURL);
085
086 break;
087 }
088 catch (LayoutFriendlyURLException lfurle) {
089 int type = lfurle.getType();
090
091 if (type == LayoutFriendlyURLException.DUPLICATE) {
092 friendlyURL = originalFriendlyURL + i;
093 }
094 else {
095 friendlyURL = StringPool.SLASH + layoutId;
096
097 break;
098 }
099 }
100 }
101
102 return friendlyURL;
103 }
104
105 public String getFriendlyURL(String friendlyURL) {
106 return FriendlyURLNormalizerUtil.normalize(friendlyURL);
107 }
108
109 public Map<Locale, String> getFriendlyURLMap(
110 long groupId, boolean privateLayout, long layoutId, String name,
111 Map<Locale, String> friendlyURLMap)
112 throws PortalException, SystemException {
113
114 Map<Locale, String> newFriendlyURLMap = new HashMap<Locale, String>();
115
116 Locale[] locales = LanguageUtil.getAvailableLocales(groupId);
117
118 for (Locale locale : locales) {
119 String friendlyURL = friendlyURLMap.get(locale);
120
121 if (Validator.isNotNull(friendlyURL)) {
122 friendlyURL = getFriendlyURL(
123 groupId, privateLayout, layoutId, name, friendlyURL);
124
125 newFriendlyURLMap.put(locale, friendlyURL);
126 }
127 }
128
129 if (newFriendlyURLMap.isEmpty()) {
130 String friendlyURL = getFriendlyURL(
131 groupId, privateLayout, layoutId, name, StringPool.BLANK);
132
133 newFriendlyURLMap.put(LocaleUtil.getSiteDefault(), friendlyURL);
134 }
135
136 return newFriendlyURLMap;
137 }
138
139 public int getNextPriority(
140 long groupId, boolean privateLayout, long parentLayoutId,
141 String sourcePrototypeLayoutUuid, int defaultPriority)
142 throws SystemException {
143
144 try {
145 int priority = defaultPriority;
146
147 if (priority < 0) {
148 Layout layout = layoutPersistence.findByG_P_P_First(
149 groupId, privateLayout, parentLayoutId,
150 new LayoutPriorityComparator(false));
151
152 priority = layout.getPriority() + 1;
153 }
154
155 if ((priority < _PRIORITY_BUFFER) &&
156 Validator.isNull(sourcePrototypeLayoutUuid)) {
157
158 LayoutSet layoutSet = layoutSetPersistence.fetchByG_P(
159 groupId, privateLayout);
160
161 if (Validator.isNotNull(
162 layoutSet.getLayoutSetPrototypeUuid()) &&
163 layoutSet.isLayoutSetPrototypeLinkEnabled()) {
164
165 priority = priority + _PRIORITY_BUFFER;
166 }
167 }
168
169 return priority;
170 }
171 catch (NoSuchLayoutException nsle) {
172 return 0;
173 }
174 }
175
176 public long getParentLayoutId(
177 long groupId, boolean privateLayout, long parentLayoutId)
178 throws SystemException {
179
180 if (parentLayoutId != LayoutConstants.DEFAULT_PARENT_LAYOUT_ID) {
181
182
183
184 Layout parentLayout = layoutPersistence.fetchByG_P_L(
185 groupId, privateLayout, parentLayoutId);
186
187 if (parentLayout == null) {
188 parentLayoutId = LayoutConstants.DEFAULT_PARENT_LAYOUT_ID;
189 }
190 }
191
192 return parentLayoutId;
193 }
194
195 public boolean hasLayoutSetPrototypeLayout(
196 LayoutSetPrototype layoutSetPrototype, String layoutUuid)
197 throws PortalException, SystemException {
198
199 Layout layout = layoutPersistence.fetchByUUID_G_P(
200 layoutUuid, layoutSetPrototype.getGroupId(), true);
201
202 if (layout != null) {
203 return true;
204 }
205
206 return false;
207 }
208
209 @Override
210 public void setBeanIdentifier(String beanIdentifier) {
211 _beanIdentifier = beanIdentifier;
212 }
213
214 public void validate(
215 long groupId, boolean privateLayout, long layoutId,
216 long parentLayoutId, String name, String type, boolean hidden,
217 Map<Locale, String> friendlyURLMap)
218 throws PortalException, SystemException {
219
220 validateName(name);
221
222 boolean firstLayout = false;
223
224 if (parentLayoutId == LayoutConstants.DEFAULT_PARENT_LAYOUT_ID) {
225 List<Layout> layouts = layoutPersistence.findByG_P_P(
226 groupId, privateLayout, parentLayoutId, 0, 1);
227
228 if (layouts.size() == 0) {
229 firstLayout = true;
230 }
231 else {
232 long firstLayoutId = layouts.get(0).getLayoutId();
233
234 if (firstLayoutId == layoutId) {
235 firstLayout = true;
236 }
237 }
238 }
239 else {
240
241
242
243
244 Layout parentLayout = layoutPersistence.findByG_P_L(
245 groupId, privateLayout, parentLayoutId);
246
247 if (!SitesUtil.isLayoutSortable(parentLayout)) {
248 throw new LayoutParentLayoutIdException(
249 LayoutParentLayoutIdException.NOT_SORTABLE);
250 }
251 }
252
253 if (firstLayout) {
254 validateFirstLayout(type);
255 }
256
257 if (!PortalUtil.isLayoutParentable(type)) {
258 if (layoutPersistence.countByG_P_P(
259 groupId, privateLayout, layoutId) > 0) {
260
261 throw new LayoutTypeException(
262 LayoutTypeException.NOT_PARENTABLE);
263 }
264 }
265
266 validateFriendlyURLs(groupId, privateLayout, layoutId, friendlyURLMap);
267 }
268
269 public void validateFirstLayout(Layout layout)
270 throws PortalException, SystemException {
271
272 Group group = layout.getGroup();
273
274 if (group.isGuest() && !hasGuestViewPermission(layout)) {
275 LayoutTypeException lte = new LayoutTypeException(
276 LayoutTypeException.FIRST_LAYOUT_PERMISSION);
277
278 throw lte;
279 }
280
281 validateFirstLayout(layout.getType());
282 }
283
284 public void validateFirstLayout(String type) throws PortalException {
285 if (Validator.isNull(type) || !PortalUtil.isLayoutFirstPageable(type)) {
286 LayoutTypeException lte = new LayoutTypeException(
287 LayoutTypeException.FIRST_LAYOUT);
288
289 lte.setLayoutType(type);
290
291 throw lte;
292 }
293 }
294
295 public void validateFriendlyURL(
296 long groupId, boolean privateLayout, long layoutId,
297 String friendlyURL)
298 throws PortalException, SystemException {
299
300 if (Validator.isNull(friendlyURL)) {
301 return;
302 }
303
304 int exceptionType = LayoutImpl.validateFriendlyURL(friendlyURL);
305
306 if (exceptionType != -1) {
307 throw new LayoutFriendlyURLException(exceptionType);
308 }
309
310 List<LayoutFriendlyURL> layoutFriendlyURLs =
311 layoutFriendlyURLPersistence.findByG_P_F(
312 groupId, privateLayout, friendlyURL);
313
314 for (LayoutFriendlyURL layoutFriendlyURL : layoutFriendlyURLs) {
315 Layout layout = layoutPersistence.findByPrimaryKey(
316 layoutFriendlyURL.getPlid());
317
318 if (layout.getLayoutId() != layoutId) {
319 throw new LayoutFriendlyURLException(
320 LayoutFriendlyURLException.DUPLICATE);
321 }
322 }
323
324 LayoutImpl.validateFriendlyURLKeyword(friendlyURL);
325
326
340
341 String layoutIdFriendlyURL = friendlyURL.substring(1);
342
343 if (Validator.isNumber(layoutIdFriendlyURL) &&
344 !layoutIdFriendlyURL.equals(String.valueOf(layoutId))) {
345
346 LayoutFriendlyURLException lfurle = new LayoutFriendlyURLException(
347 LayoutFriendlyURLException.POSSIBLE_DUPLICATE);
348
349 lfurle.setKeywordConflict(layoutIdFriendlyURL);
350
351 throw lfurle;
352 }
353 }
354
355 public void validateFriendlyURLs(
356 long groupId, boolean privateLayout, long layoutId,
357 Map<Locale, String> friendlyURLMap)
358 throws PortalException, SystemException {
359
360 for (Map.Entry<Locale, String> entry : friendlyURLMap.entrySet()) {
361 String friendlyURL = entry.getValue();
362
363 validateFriendlyURL(groupId, privateLayout, layoutId, friendlyURL);
364 }
365 }
366
367 public void validateName(String name) throws PortalException {
368 if (Validator.isNull(name)) {
369 throw new LayoutNameException();
370 }
371 }
372
373 public void validateName(String name, String languageId)
374 throws PortalException {
375
376 String defaultLanguageId = LocaleUtil.toLanguageId(
377 LocaleUtil.getSiteDefault());
378
379 if (defaultLanguageId.equals(languageId)) {
380 validateName(name);
381 }
382 }
383
384 public void validateParentLayoutId(
385 long groupId, boolean privateLayout, long layoutId,
386 long parentLayoutId)
387 throws PortalException, SystemException {
388
389 Layout layout = layoutPersistence.findByG_P_L(
390 groupId, privateLayout, layoutId);
391
392 if (parentLayoutId == layout.getParentLayoutId()) {
393 return;
394 }
395
396
397
398 if (parentLayoutId == LayoutConstants.DEFAULT_PARENT_LAYOUT_ID) {
399 return;
400 }
401
402
403
404 Layout parentLayout = layoutPersistence.findByG_P_L(
405 groupId, privateLayout, parentLayoutId);
406
407 if (!PortalUtil.isLayoutParentable(parentLayout)) {
408 throw new LayoutParentLayoutIdException(
409 LayoutParentLayoutIdException.NOT_PARENTABLE);
410 }
411
412
413
414
415 if (!SitesUtil.isLayoutSortable(parentLayout)) {
416 throw new LayoutParentLayoutIdException(
417 LayoutParentLayoutIdException.NOT_SORTABLE);
418 }
419
420
421
422 if (PortalUtil.isLayoutDescendant(layout, parentLayoutId)) {
423 throw new LayoutParentLayoutIdException(
424 LayoutParentLayoutIdException.SELF_DESCENDANT);
425 }
426
427
428
429 if (layout.getParentLayoutId() ==
430 LayoutConstants.DEFAULT_PARENT_LAYOUT_ID) {
431
432 List<Layout> layouts = layoutPersistence.findByG_P_P(
433 groupId, privateLayout,
434 LayoutConstants.DEFAULT_PARENT_LAYOUT_ID, 0, 2);
435
436
437
438
439 long firstLayoutId = layouts.get(0).getLayoutId();
440
441 if (firstLayoutId == layoutId) {
442 Layout secondLayout = layouts.get(1);
443
444 if (Validator.isNull(secondLayout.getType()) ||
445 !PortalUtil.isLayoutFirstPageable(secondLayout.getType())) {
446
447 throw new LayoutParentLayoutIdException(
448 LayoutParentLayoutIdException.FIRST_LAYOUT_TYPE);
449 }
450 }
451 }
452 }
453
454 protected boolean hasGuestViewPermission(Layout layout)
455 throws PortalException, SystemException {
456
457 Role role = RoleLocalServiceUtil.getRole(
458 layout.getCompanyId(), RoleConstants.GUEST);
459
460 return resourcePermissionLocalService.hasResourcePermission(
461 layout.getCompanyId(), Layout.class.getName(),
462 ResourceConstants.SCOPE_INDIVIDUAL,
463 String.valueOf(layout.getPlid()), role.getRoleId(),
464 ActionKeys.VIEW);
465 }
466
467 @BeanReference(type = LayoutFriendlyURLPersistence.class)
468 protected LayoutFriendlyURLPersistence layoutFriendlyURLPersistence;
469
470 @BeanReference(type = LayoutPersistence.class)
471 protected LayoutPersistence layoutPersistence;
472
473 @BeanReference(type = LayoutSetPersistence.class)
474 protected LayoutSetPersistence layoutSetPersistence;
475
476 @BeanReference(type = ResourcePermissionLocalService.class)
477 protected ResourcePermissionLocalService resourcePermissionLocalService;
478
479 private static final int _PRIORITY_BUFFER = 1000000;
480
481 private String _beanIdentifier;
482
483 }