/** * Aptana Studio * Copyright (c) 2005-2011 by Appcelerator, Inc. All Rights Reserved. * Licensed under the terms of the GNU Public License (GPL) v3 (with exceptions). * Please see the license.html included with this distribution for details. * Any modifications to this file must keep this entire header intact. */ package com.aptana.editor.php.internal.model.impl; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import com.aptana.editor.php.core.model.IMember; import com.aptana.editor.php.core.model.IModelElement; import com.aptana.editor.php.core.model.ISourceModule; import com.aptana.editor.php.core.model.ISourceRange; import com.aptana.editor.php.core.model.IType; import com.aptana.editor.php.indexer.EntryUtils; import com.aptana.editor.php.indexer.IElementEntry; import com.aptana.editor.php.indexer.IElementsIndex; import com.aptana.editor.php.indexer.PHPGlobalIndexer; import com.aptana.editor.php.internal.core.builder.IModule; import com.aptana.editor.php.internal.indexer.AbstractPHPEntryValue; import com.aptana.editor.php.internal.indexer.ElementsIndexingUtils; import com.aptana.editor.php.internal.model.utils.ModelUtils; import com.aptana.editor.php.internal.model.utils.TypeUtils; /** * Abstract member. * * @author Denis Denisenko */ public abstract class AbstractMember extends AbstractModelElement implements IMember { /** * Entry. */ private IElementEntry entry; /** * AbstractMember constructor. * * @param entry * - entry. */ protected AbstractMember(IElementEntry entry) { this.entry = entry; } /** * {@inheritDoc} */ public ISourceModule getSourceModule() { return ModelUtils.convertModule(entry.getModule()); } /** * {@inheritDoc} */ public boolean exists() { IElementsIndex index = PHPGlobalIndexer.getInstance().getIndex(); List<IElementEntry> entries = index.getEntries(entry.getCategory(), entry.getEntryPath()); if (entries == null || entries.size() == 0) { return false; } for (IElementEntry currentEntry : entries) { if (entry.equals(currentEntry)) { return true; } } return false; } /** * {@inheritDoc} */ public String getElementName() { return ElementsIndexingUtils.getLastNameInPath(entry.getEntryPath()); } public IType getDeclaringType() { if (EntryUtils.isType(entry)) { return null; } IElementEntry typeEntry = TypeUtils.getDeclaringType(entry); if (typeEntry == null) { return null; } return (IType) ModelUtils.convertEntry(typeEntry); } /** * {@inheritDoc} */ public IModelElement getParent() { // return module for top-level entries if (!entry.getEntryPath().contains(Character.toString(IElementsIndex.DELIMITER))) { return ModelUtils.convertModule(entry.getModule()); } // looking for a parent String entryPathStr = entry.getEntryPath(); if (entryPathStr == null || entryPathStr.length() == 0) { return ModelUtils.convertModule(entry.getModule()); } IPath entryPath = new Path(entryPathStr); if (entryPath.segmentCount() < 2) { return ModelUtils.convertModule(entry.getModule()); } IPath parentPath = entryPath.removeLastSegments(1); List<IElementEntry> entries = getModuleEntries(-1, pathToString(parentPath)); if (entries.size() == 0) { return ModelUtils.convertModule(entry.getModule()); } return ModelUtils.convertEntry(entries.iterator().next()); } /** * {@inheritDoc} */ public List<IModelElement> getChildren() { // //return top-level entries // if (!entry.getEntryPath().contains(Character.toString(IElementsIndex.DELIMITER))) // { // return ModelUtils.convertEntries(getModuleEntries()); // } // looking for the children List<IElementEntry> entries = getModuleEntriesStartingWith(-1, entry.getEntryPath()); return ModelUtils.convertEntries(entries); } /** * {@inheritDoc} */ public boolean hasChildren() { // return top-level entries if (!entry.getEntryPath().contains(Character.toString(IElementsIndex.DELIMITER))) { return getModuleEntries().size() != 0; } // looking for the children return getModuleEntriesStartingWith(-1, entry.getEntryPath()).size() != 0; } /** * {@inheritDoc} */ public ISourceRange getSourceRange() { if (getEntry().getValue() instanceof AbstractPHPEntryValue) { // TODO add length when it is available during indexing return new SourceRange(((AbstractPHPEntryValue) getEntry().getValue()).getStartOffset()); } return new SourceRange(0); } /** * Gets entry. * * @return entry. */ public IElementEntry getEntry() { return entry; } /** * Filters entries by module and returns only those that are declared in a module specified. * * @param entries * - entries to filter. * @return filtered entries. */ protected List<IElementEntry> filterByModule(List<IElementEntry> entries, IModule module) { if (entries == null || entries.size() == 0) { return Collections.emptyList(); } List<IElementEntry> result = new ArrayList<IElementEntry>(); for (IElementEntry currentEntry : entries) { if (module.equals(currentEntry.getModule())) { result.add(currentEntry); } } return result; } /** * Gets current module entries starting with the entry path specified excluding the current entry. * * @param category * - category. -1 for any category. * @param entryPath * - entry path. null or empty path means no filtering. * @return entries */ protected List<IElementEntry> getModuleEntries(int category, String entryPath) { List<IElementEntry> moduleEntries = getModuleEntries(); List<IElementEntry> correctPathEntries = new ArrayList<IElementEntry>(); if (entryPath == null || entryPath.length() == 0) { correctPathEntries = moduleEntries; } else { for (IElementEntry currentEntry : moduleEntries) { if (entryPath.equals(currentEntry.getEntryPath()) && !entry.equals(currentEntry)) { correctPathEntries.add(currentEntry); } } } if (category == -1) { return correctPathEntries; } List<IElementEntry> result = new ArrayList<IElementEntry>(); for (IElementEntry currentEntry : correctPathEntries) { if (currentEntry.getCategory() == category) { result.add(currentEntry); } } return result; } /** * Gets current module entries starting with the entry path specified, excluding the current entry. * * @param category * - category. -1 for any category. * @param entryPath * - entry path. null or empty path means no filtering. * @return entries */ protected List<IElementEntry> getModuleEntriesStartingWith(int category, String entryPath) { List<IElementEntry> moduleEntries = getModuleEntries(); List<IElementEntry> correctPathEntries = new ArrayList<IElementEntry>(); if (entryPath == null || entryPath.length() == 0) { correctPathEntries = moduleEntries; } else { for (IElementEntry currentEntry : moduleEntries) { if (currentEntry.getEntryPath().startsWith(entryPath) && !entry.equals(currentEntry)) { correctPathEntries.add(currentEntry); } } } if (category == -1) { return correctPathEntries; } List<IElementEntry> result = new ArrayList<IElementEntry>(); for (IElementEntry currentEntry : correctPathEntries) { if (currentEntry.getCategory() == category) { result.add(currentEntry); } } return result; } /** * Serializes path to string. * * @param path * - path. * @return path string */ protected String pathToString(IPath path) { if (path == null || path.segmentCount() == 0) { return ""; //$NON-NLS-1$ } StringBuilder builder = new StringBuilder(); String[] segments = path.segments(); for (int i = 0; i < path.segmentCount() - 1; i++) { builder.append(segments[i]); builder.append(IElementsIndex.DELIMITER); } builder.append(segments[segments.length - 1]); return builder.toString(); } /** * Gets current module entries. * * @return current module entries. */ private List<IElementEntry> getModuleEntries() { IModule module = entry.getModule(); if (module == null) { return Collections.emptyList(); } IElementsIndex index = PHPGlobalIndexer.getInstance().getIndex(); return index.getModuleEntries(module); } /** * {@inheritDoc} */ public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((entry == null) ? 0 : entry.hashCode()); return result; } /** * {@inheritDoc} */ public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; AbstractMember other = (AbstractMember) obj; if (entry == null) { if (other.entry != null) return false; } else if (!entry.equals(other.entry)) return false; return true; } }